summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/error.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/error.c')
-rw-r--r--contrib/gcc/cp/error.c2671
1 files changed, 1660 insertions, 1011 deletions
diff --git a/contrib/gcc/cp/error.c b/contrib/gcc/cp/error.c
index 4da1d2f..594d4e4 100644
--- a/contrib/gcc/cp/error.c
+++ b/contrib/gcc/cp/error.c
@@ -1,7 +1,7 @@
/* Call-backs for C++ error reporting.
This code is non-reentrant.
- Copyright (C) 1993, 94-97, 1998, 1999 Free Software Foundation, Inc.
-
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002
+ Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
@@ -23,240 +23,373 @@ Boston, MA 02111-1307, USA. */
#include "system.h"
#include "tree.h"
#include "cp-tree.h"
+#include "real.h"
#include "obstack.h"
#include "toplev.h"
-
-typedef 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
-
-/* Obstack where we build text strings for overloading, etc. */
-static struct obstack scratch_obstack;
-static char *scratch_firstobj;
-
-# define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0)
-# define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C)))
-# define OB_PUTC2(C1,C2) \
- (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2)))
-# define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1))
-# define OB_PUTID(ID) \
- (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \
- IDENTIFIER_LENGTH (ID)))
-# define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S)))
-# define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0'))
-# define OB_PUTI(CST) do { sprintf (digit_buffer, 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)[-1] == '>') \
- ? OB_PUTC2 (' ', '>') : OB_PUTC ('>'))
-
-# define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t)))
+#include "flags.h"
+#include "diagnostic.h"
enum pad { none, before, after };
-static void dump_type PROTO((tree, int));
-static void dump_type_real PROTO((tree, int, int));
-static void dump_simple_decl PROTO((tree, tree, int));
-static void dump_decl PROTO((tree, int));
-static void dump_function_decl PROTO((tree, int));
-static void dump_expr PROTO((tree, int));
-static void dump_unary_op PROTO((char *, tree, int));
-static void dump_binary_op PROTO((char *, tree));
-static void dump_aggr_type PROTO((tree, int, int));
-static void dump_type_prefix PROTO((tree, int, int));
-static void dump_type_suffix PROTO((tree, int, int));
-static void dump_function_name PROTO((tree));
-static void dump_expr_list PROTO((tree));
-static void dump_global_iord PROTO((tree));
-static void dump_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 char *aggr_variety PROTO((tree));
-static tree ident_fndecl PROTO((tree));
-static int interesting_scope_p PROTO((tree));
+#define sorry_for_unsupported_tree(T) \
+ sorry ("`%s' not supported by %s", tree_code_name[(int) TREE_CODE (T)], \
+ __FUNCTION__)
+
+#define print_scope_operator(BUFFER) output_add_string ((BUFFER), "::")
+#define print_left_paren(BUFFER) output_add_character ((BUFFER), '(')
+#define print_right_paren(BUFFER) output_add_character ((BUFFER), ')')
+#define print_left_bracket(BUFFER) output_add_character ((BUFFER), '[')
+#define print_right_bracket(BUFFER) output_add_character ((BUFFER), ']')
+#define print_template_argument_list_start(BUFFER) \
+ print_non_consecutive_character ((BUFFER), '<')
+#define print_template_argument_list_end(BUFFER) \
+ print_non_consecutive_character ((BUFFER), '>')
+#define print_whitespace(BUFFER, TFI) \
+ do { \
+ output_add_space (BUFFER); \
+ put_whitespace (TFI) = none; \
+ } while (0)
+#define print_tree_identifier(BUFFER, TID) \
+ output_add_string ((BUFFER), IDENTIFIER_POINTER (TID))
+#define print_identifier(BUFFER, ID) output_add_string ((BUFFER), (ID))
+#define separate_with_comma(BUFFER) output_add_string ((BUFFER), ", ")
+
+/* The global buffer where we dump everything. It is there only for
+ transitional purpose. It is expected, in the near future, to be
+ completely removed. */
+static output_buffer scratch_buffer_rec;
+static output_buffer *scratch_buffer = &scratch_buffer_rec;
+
+# define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T)))
+
+#define reinit_global_formatting_buffer() \
+ output_clear_message_text (scratch_buffer)
+
+static const char *args_to_string PARAMS ((tree, int));
+static const char *assop_to_string PARAMS ((enum tree_code, int));
+static const char *code_to_string PARAMS ((enum tree_code, int));
+static const char *cv_to_string PARAMS ((tree, int));
+static const char *decl_to_string PARAMS ((tree, int));
+static const char *expr_to_string PARAMS ((tree, int));
+static const char *fndecl_to_string PARAMS ((tree, int));
+static const char *op_to_string PARAMS ((enum tree_code, int));
+static const char *parm_to_string PARAMS ((int, int));
+static const char *type_to_string PARAMS ((tree, int));
+
+static void dump_type PARAMS ((tree, int));
+static void dump_typename PARAMS ((tree, int));
+static void dump_simple_decl PARAMS ((tree, tree, int));
+static void dump_decl PARAMS ((tree, int));
+static void dump_template_decl PARAMS ((tree, int));
+static void dump_function_decl PARAMS ((tree, int));
+static void dump_expr PARAMS ((tree, int));
+static void dump_unary_op PARAMS ((const char *, tree, int));
+static void dump_binary_op PARAMS ((const char *, tree, int));
+static void dump_aggr_type PARAMS ((tree, int));
+static enum pad dump_type_prefix PARAMS ((tree, int));
+static void dump_type_suffix PARAMS ((tree, int));
+static void dump_function_name PARAMS ((tree, int));
+static void dump_expr_list PARAMS ((tree, int));
+static void dump_global_iord PARAMS ((tree));
+static enum pad dump_qualifiers PARAMS ((tree, enum pad));
+static void dump_char PARAMS ((int));
+static void dump_parameters PARAMS ((tree, int));
+static void dump_exception_spec PARAMS ((tree, int));
+static const char *class_key_or_enum PARAMS ((tree));
+static void dump_template_argument PARAMS ((tree, int));
+static void dump_template_argument_list PARAMS ((tree, int));
+static void dump_template_parameter PARAMS ((tree, int));
+static void dump_template_bindings PARAMS ((tree, tree));
+static void dump_scope PARAMS ((tree, int));
+static void dump_template_parms PARAMS ((tree, int, int));
+
+static const char *function_category PARAMS ((tree));
+static void lang_print_error_function PARAMS ((diagnostic_context *,
+ const char *));
+static void maybe_print_instantiation_context PARAMS ((output_buffer *));
+static void print_instantiation_full_context PARAMS ((output_buffer *));
+static void print_instantiation_partial_context PARAMS ((output_buffer *, tree,
+ const char *, int));
+static void cp_diagnostic_starter PARAMS ((output_buffer *,
+ diagnostic_context *));
+static void cp_diagnostic_finalizer PARAMS ((output_buffer *,
+ diagnostic_context *));
+static void cp_print_error_function PARAMS ((output_buffer *,
+ diagnostic_context *));
+
+static int cp_printer PARAMS ((output_buffer *));
+static void print_non_consecutive_character PARAMS ((output_buffer *, int));
+static void print_integer PARAMS ((output_buffer *, HOST_WIDE_INT));
+static tree locate_error PARAMS ((const char *, va_list));
void
init_error ()
{
- gcc_obstack_init (&scratch_obstack);
- scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0);
+ print_error_function = lang_print_error_function;
+ diagnostic_starter (global_dc) = cp_diagnostic_starter;
+ diagnostic_finalizer (global_dc) = cp_diagnostic_finalizer;
+ diagnostic_format_decoder (global_dc) = cp_printer;
+
+ init_output_buffer (scratch_buffer, /* prefix */NULL, /* line-width */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;
+ int flags;
{
- if (scope == NULL_TREE
- || scope == global_namespace)
- return 0;
+ int f = ~TFF_RETURN_TYPE & (flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF));
+
+ if (scope == NULL_TREE)
+ return;
- return (TREE_CODE (scope) == NAMESPACE_DECL
- || AGGREGATE_TYPE_P (scope));
+ if (TREE_CODE (scope) == NAMESPACE_DECL)
+ {
+ if (scope != global_namespace)
+ {
+ dump_decl (scope, f);
+ print_scope_operator (scratch_buffer);
+ }
+ }
+ else if (AGGREGATE_TYPE_P (scope))
+ {
+ dump_type (scope, f);
+ print_scope_operator (scratch_buffer);
+ }
+ else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL)
+ {
+ dump_function_decl (scope, f);
+ print_scope_operator (scratch_buffer);
+ }
}
-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;
+ for (ix = 0; ix != 3; ix++)
+ if (masks[ix] & quals)
+ {
+ if (p == before)
+ output_add_space (scratch_buffer);
+ p = before;
+ print_identifier (scratch_buffer, names[ix]);
+ }
+ if (do_after)
+ output_add_space (scratch_buffer);
+ }
+ else
+ p = none;
+ return p;
+}
- case TYPE_QUAL_VOLATILE:
- OB_PUTS ("volatile");
- break;
+/* This must be large enough to hold any printed integer or floating-point
+ value. */
+static char digit_buffer[128];
- case TYPE_QUAL_RESTRICT:
- OB_PUTS ("__restrict");
- break;
+/* Dump the template ARGument under control of FLAGS. */
- case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
- OB_PUTS ("const volatile");
- break;
+static void
+dump_template_argument (arg, flags)
+ tree arg;
+ int flags;
+{
+ if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
+ dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
+ else
+ dump_expr (arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM);
+}
- case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
- OB_PUTS ("const __restrict");
- break;
+/* Dump a template-argument-list ARGS (always a TREE_VEC) under control
+ of FLAGS. */
- case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
- OB_PUTS ("volatile __restrict");
- break;
+static void
+dump_template_argument_list (args, flags)
+ tree args;
+ int flags;
+{
+ int n = TREE_VEC_LENGTH (args);
+ int need_comma = 0;
+ int i;
- case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
- OB_PUTS ("const volatile __restrict");
- break;
+ for (i = 0; i< n; ++i)
+ {
+ if (need_comma)
+ separate_with_comma (scratch_buffer);
+ dump_template_argument (TREE_VEC_ELT (args, i), flags);
+ need_comma = 1;
+ }
+}
- default:
- my_friendly_abort (0);
- }
- if (p == after) OB_PUTC (' ');
+/* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS. */
+
+static void
+dump_template_parameter (parm, flags)
+ tree parm;
+ int flags;
+{
+ tree p = TREE_VALUE (parm);
+ tree a = TREE_PURPOSE (parm);
+
+ if (TREE_CODE (p) == TYPE_DECL)
+ {
+ if (flags & TFF_DECL_SPECIFIERS)
+ {
+ print_identifier (scratch_buffer, "class");
+ if (DECL_NAME (p))
+ {
+ output_add_space (scratch_buffer);
+ print_tree_identifier (scratch_buffer, DECL_NAME (p));
+ }
+ }
+ else if (DECL_NAME (p))
+ print_tree_identifier (scratch_buffer, DECL_NAME (p));
+ else
+ print_identifier (scratch_buffer, "{template default argument error}");
+ }
+ else
+ dump_decl (p, flags | TFF_DECL_SPECIFIERS);
+
+ if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE)
+ {
+ output_add_string (scratch_buffer, " = ");
+ if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
+ dump_type (a, flags & ~TFF_CHASE_TYPEDEF);
+ else
+ dump_expr (a, flags | TFF_EXPR_IN_PARENS);
}
}
-/* This must be large enough to hold any printed integer or floating-point
- value. */
-static char digit_buffer[128];
+/* Dump, under control of FLAGS, a template-parameter-list binding.
+ PARMS is a TREE_LIST of TREE_VEC of TREE_LIST and ARGS is a
+ TREE_VEC. */
-/* Dump into the obstack a human-readable equivalent of TYPE. */
+static void
+dump_template_bindings (parms, args)
+ tree parms, args;
+{
+ int need_comma = 0;
+
+ while (parms)
+ {
+ tree p = TREE_VALUE (parms);
+ int lvl = TMPL_PARMS_DEPTH (parms);
+ int arg_idx = 0;
+ int i;
+
+ for (i = 0; i < TREE_VEC_LENGTH (p); ++i)
+ {
+ tree arg = NULL_TREE;
+
+ /* Don't crash if we had an invalid argument list. */
+ if (TMPL_ARGS_DEPTH (args) >= lvl)
+ {
+ tree lvl_args = TMPL_ARGS_LEVEL (args, lvl);
+ if (NUM_TMPL_ARGS (lvl_args) > arg_idx)
+ arg = TREE_VEC_ELT (lvl_args, arg_idx);
+ }
+
+ if (need_comma)
+ separate_with_comma (scratch_buffer);
+ dump_template_parameter (TREE_VEC_ELT (p, i), TFF_PLAIN_IDENTIFIER);
+ output_add_string (scratch_buffer, " = ");
+ if (arg)
+ dump_template_argument (arg, TFF_PLAIN_IDENTIFIER);
+ else
+ print_identifier (scratch_buffer, "<missing>");
+
+ ++arg_idx;
+ need_comma = 1;
+ }
+
+ parms = TREE_CHAIN (parms);
+ }
+}
+
+/* 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;
+ int flags;
{
if (t == NULL_TREE)
return;
-
+
if (TYPE_PTRMEMFUNC_P (t))
goto offset_type;
switch (TREE_CODE (t))
{
- case ERROR_MARK:
- OB_PUTS ("{error}");
- break;
-
case UNKNOWN_TYPE:
- OB_PUTS ("{unknown type}");
+ print_identifier (scratch_buffer, "<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:
- OB_PUTID (t);
+ print_tree_identifier (scratch_buffer, t);
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:
- if (TYPE_LANG_SPECIFIC (t)
- && (IS_SIGNATURE_POINTER (t) || IS_SIGNATURE_REFERENCE (t)))
- {
- dump_qualifiers (t, after);
- dump_type_real (SIGNATURE_TYPE (t), v, canonical_name);
- if (IS_SIGNATURE_POINTER (t))
- OB_PUTC ('*');
- else
- OB_PUTC ('&');
- }
- else
- dump_aggr_type (t, v, canonical_name);
+ dump_aggr_type (t, flags);
break;
case TYPE_DECL:
+ if (flags & TFF_CHASE_TYPEDEF)
+ {
+ 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 & ~TFF_DECL_SPECIFIERS);
break;
case COMPLEX_TYPE:
- OB_PUTS ("complex ");
- dump_type_real (TREE_TYPE (t), v, canonical_name);
+ output_add_string (scratch_buffer, "__complex__ ");
+ dump_type (TREE_TYPE (t), flags);
+ break;
+
+ case VECTOR_TYPE:
+ output_add_string (scratch_buffer, "vector ");
+ dump_type (TREE_TYPE (t), flags);
break;
case INTEGER_TYPE:
if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))
- OB_PUTS ("unsigned ");
+ output_add_string (scratch_buffer, "unsigned ");
else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t))
- OB_PUTS ("signed ");
+ output_add_string (scratch_buffer, "signed ");
/* fall through. */
case REAL_TYPE:
@@ -265,53 +398,43 @@ dump_type_real (t, v, canonical_name)
{
tree type;
dump_qualifiers (t, after);
- type = canonical_name ? TYPE_MAIN_VARIANT (t) : t;
+ type = flags & TFF_CHASE_TYPEDEF ? TYPE_MAIN_VARIANT (t) : t;
if (TYPE_NAME (type) && TYPE_IDENTIFIER (type))
- OB_PUTID (TYPE_IDENTIFIER (type));
+ print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (type));
else
/* Types like intQI_type_node and friends have no names.
These don't come up in user error messages, but it's nice
to be able to print them from the debugger. */
- OB_PUTS ("{anonymous}");
+ print_identifier (scratch_buffer, "<anonymous>");
}
break;
case TEMPLATE_TEMPLATE_PARM:
- if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t))
- {
- /* For parameters inside template signature. */
- if (TYPE_IDENTIFIER (t))
- OB_PUTID (TYPE_IDENTIFIER (t));
- else
- OB_PUTS ("{anonymous template template parm}");
- }
+ /* For parameters inside template signature. */
+ if (TYPE_IDENTIFIER (t))
+ print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
else
- {
- int i;
- tree args = TYPE_TI_ARGS (t);
- OB_PUTID (TYPE_IDENTIFIER (t));
- OB_PUTC ('<');
- for (i = 0; i < TREE_VEC_LENGTH (args); i++)
- {
- tree arg = TREE_VEC_ELT (args, i);
- if (TREE_CODE_CLASS (TREE_CODE (arg)) == 't'
- || TREE_CODE (arg) == TEMPLATE_DECL)
- dump_type_real (arg, 0, canonical_name);
- else
- dump_expr (arg, 0);
- if (i < TREE_VEC_LENGTH (args)-1)
- OB_PUTC2 (',', ' ');
- }
- OB_END_TEMPLATE_ID ();
- }
+ print_identifier
+ (scratch_buffer, "<anonymous template template parameter>");
+ break;
+
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ {
+ tree args = TYPE_TI_ARGS (t);
+ print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
+ print_template_argument_list_start (scratch_buffer);
+ dump_template_argument_list (args, flags);
+ print_template_argument_list_end (scratch_buffer);
+ }
break;
case TEMPLATE_TYPE_PARM:
dump_qualifiers (t, after);
if (TYPE_IDENTIFIER (t))
- OB_PUTID (TYPE_IDENTIFIER (t));
+ print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
else
- OB_PUTS ("{anonymous template type parm}");
+ print_identifier
+ (scratch_buffer, "<anonymous template type parameter>");
break;
/* This is not always necessary for pointers and such, but doing this
@@ -323,31 +446,61 @@ 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);
- OB_PUTS ("::");
- dump_decl (TYPENAME_TYPE_FULLNAME (t), v);
+ output_add_string (scratch_buffer, "typename ");
+ dump_typename (t, flags);
+ break;
+
+ case UNBOUND_CLASS_TEMPLATE:
+ dump_type (TYPE_CONTEXT (t), flags);
+ print_scope_operator (scratch_buffer);
+ print_identifier (scratch_buffer, "template ");
+ dump_type (DECL_NAME (TYPE_NAME (t)), flags);
break;
case TYPEOF_TYPE:
- OB_PUTS ("__typeof (");
- dump_expr (TYPE_FIELDS (t), 1);
- OB_PUTC (')');
+ output_add_string (scratch_buffer, "__typeof (");
+ dump_expr (TYPE_FIELDS (t), flags & ~TFF_EXPR_IN_PARENS);
+ print_left_paren (scratch_buffer);
break;
default:
- sorry ("`%s' not supported by dump_type",
- tree_code_name[(int) TREE_CODE (t)]);
+ sorry_for_unsupported_tree (t);
+ /* Fall through to error. */
+
+ case ERROR_MARK:
+ print_identifier (scratch_buffer, "<type error>");
+ break;
}
}
-static char *
-aggr_variety (t)
+/* Dump a TYPENAME_TYPE. We need to notice when the context is itself
+ a TYPENAME_TYPE. */
+
+static void
+dump_typename (t, flags)
+ tree t;
+ int flags;
+{
+ tree ctx = TYPE_CONTEXT (t);
+
+ if (TREE_CODE (ctx) == TYPENAME_TYPE)
+ dump_typename (ctx, flags);
+ else
+ dump_type (ctx, flags & ~TFF_CLASS_KEY_OR_ENUM);
+ print_scope_operator (scratch_buffer);
+ dump_decl (TYPENAME_TYPE_FULLNAME (t), flags);
+}
+
+/* Return the name of the supplied aggregate, or enumeral type. */
+
+static const char *
+class_key_or_enum (t)
tree t;
{
if (TREE_CODE (t) == ENUMERAL_TYPE)
@@ -356,64 +509,72 @@ aggr_variety (t)
return "union";
else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t))
return "class";
- else if (TYPE_LANG_SPECIFIC (t) && IS_SIGNATURE (t))
- return "signature";
else
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;
+ int flags;
{
tree name;
- char *variety = aggr_variety (t);
+ const char *variety = class_key_or_enum (t);
+ int typdef = 0;
+ int tmplate = 0;
dump_qualifiers (t, after);
- if (v > 0)
+ if (flags & TFF_CLASS_KEY_OR_ENUM)
{
- OB_PUTCP (variety);
- OB_PUTC (' ');
+ print_identifier (scratch_buffer, variety);
+ output_add_space (scratch_buffer);
}
-
- name = TYPE_NAME (canonical_name ? TYPE_MAIN_VARIANT (t) : t);
- if (name && CP_DECL_CONTEXT (name) != global_namespace)
+ if (flags & TFF_CHASE_TYPEDEF)
+ t = TYPE_MAIN_VARIANT (t);
+
+ 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 | TFF_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);
- /* kludge around weird behavior on g++.brendan/line1.C */
- if (name && TREE_CODE (name) != IDENTIFIER_NODE)
- name = DECL_NAME (name);
+ while (DECL_TEMPLATE_INFO (tpl))
+ tpl = DECL_TI_TEMPLATE (tpl);
+ name = tpl;
+ }
+ name = DECL_NAME (name);
+ }
if (name == 0 || ANON_AGGRNAME_P (name))
{
- OB_PUTS ("{anonymous");
- if (!v)
- {
- OB_PUTC (' ');
- OB_PUTCP (variety);
- }
- OB_PUTC ('}');
+ if (flags & TFF_CLASS_KEY_OR_ENUM)
+ print_identifier (scratch_buffer, "<anonymous>");
+ else
+ output_printf (scratch_buffer, "<anonymous %s>", variety);
}
else
- OB_PUTID (name);
+ print_tree_identifier (scratch_buffer, name);
+ if (tmplate)
+ dump_template_parms (TYPE_TEMPLATE_INFO (t),
+ !CLASSTYPE_USE_TEMPLATE (t),
+ flags & ~TFF_TEMPLATE_HEADER);
}
/* Dump into the obstack the initial part of the output for a given type.
@@ -425,94 +586,87 @@ 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 *[]&.
-static void
-dump_type_prefix (t, v, canonical_name)
+ 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 enum pad
+dump_type_prefix (t, flags)
tree t;
- int v; /* verbosity */
- int canonical_name;
+ int flags;
{
+ enum pad padding = before;
+
if (TYPE_PTRMEMFUNC_P (t))
{
t = TYPE_PTRMEMFUNC_FN_TYPE (t);
goto offset_type;
}
-
+
switch (TREE_CODE (t))
{
case POINTER_TYPE:
case REFERENCE_TYPE:
{
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 (TREE_CODE (sub) == ARRAY_TYPE)
+ {
+ output_add_space (scratch_buffer);
+ print_left_paren (scratch_buffer);
+ }
+ output_add_character
+ (scratch_buffer, "&*"[TREE_CODE (t) == POINTER_TYPE]);
+ padding = dump_qualifiers (t, before);
}
}
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)
+ output_add_space (scratch_buffer);
+ dump_type (TYPE_OFFSET_BASETYPE (t), flags);
+ print_scope_operator (scratch_buffer);
}
- OB_PUTC ('*');
- dump_qualifiers (t, none);
+ output_add_character (scratch_buffer, '*');
+ 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)
+ output_add_space (scratch_buffer);
+ print_left_paren (scratch_buffer);
+ 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)
+ output_add_space (scratch_buffer);
+ print_left_paren (scratch_buffer);
+ padding = none;
+ dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags);
+ print_scope_operator (scratch_buffer);
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:
@@ -520,6 +674,7 @@ dump_type_prefix (t, v, canonical_name)
case RECORD_TYPE:
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
case TREE_LIST:
case TYPE_DECL:
case TREE_VEC:
@@ -528,20 +683,28 @@ dump_type_prefix (t, v, canonical_name)
case VOID_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
- dump_type_real (t, v, canonical_name);
+ case VECTOR_TYPE:
+ dump_type (t, flags);
+ padding = before;
break;
-
+
default:
- sorry ("`%s' not supported by dump_type_prefix",
- tree_code_name[(int) TREE_CODE (t)]);
+ sorry_for_unsupported_tree (t);
+ /* fall through. */
+ case ERROR_MARK:
+ print_identifier (scratch_buffer, "<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;
+ int flags;
{
if (TYPE_PTRMEMFUNC_P (t))
t = TYPE_PTRMEMFUNC_FN_TYPE (t);
@@ -552,8 +715,8 @@ dump_type_suffix (t, v, canonical_name)
case REFERENCE_TYPE:
case OFFSET_TYPE:
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
- OB_PUTC (')');
- dump_type_suffix (TREE_TYPE (t), v, canonical_name);
+ print_right_paren (scratch_buffer);
+ dump_type_suffix (TREE_TYPE (t), flags);
break;
/* Can only be reached through function pointer */
@@ -561,42 +724,45 @@ dump_type_suffix (t, v, canonical_name)
case METHOD_TYPE:
{
tree arg;
- OB_PUTC (')');
+ print_right_paren (scratch_buffer);
arg = TYPE_ARG_TYPES (t);
if (TREE_CODE (t) == METHOD_TYPE)
arg = TREE_CHAIN (arg);
/* 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 & ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
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_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags);
+ dump_type_suffix (TREE_TYPE (t), flags);
break;
}
case ARRAY_TYPE:
- OB_PUTC ('[');
+ print_left_bracket (scratch_buffer);
if (TYPE_DOMAIN (t))
{
- if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST)
- OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1);
+ if (host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0))
+ print_integer
+ (scratch_buffer,
+ tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0) + 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 & ~TFF_EXPR_IN_PARENS);
else
- dump_expr (fold (build_binary_op
+ dump_expr (fold (cp_build_binary_op
(PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)),
- integer_one_node)), 0);
+ integer_one_node)),
+ flags & ~TFF_EXPR_IN_PARENS);
}
- OB_PUTC (']');
- dump_type_suffix (TREE_TYPE (t), v, canonical_name);
+ print_right_bracket (scratch_buffer);
+ dump_type_suffix (TREE_TYPE (t), flags);
break;
-
+
case ENUMERAL_TYPE:
- case ERROR_MARK:
case IDENTIFIER_NODE:
case INTEGER_TYPE:
case BOOLEAN_TYPE:
@@ -604,6 +770,7 @@ dump_type_suffix (t, v, canonical_name)
case RECORD_TYPE:
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
case TREE_LIST:
case TYPE_DECL:
case TREE_VEC:
@@ -612,208 +779,151 @@ dump_type_suffix (t, v, canonical_name)
case VOID_TYPE:
case TYPENAME_TYPE:
case COMPLEX_TYPE:
+ case VECTOR_TYPE:
break;
default:
- sorry ("`%s' not supported by dump_type_suffix",
- tree_code_name[(int) TREE_CODE (t)]);
+ sorry_for_unsupported_tree (t);
+ case ERROR_MARK:
+ /* Don't mark it here, we should have already done in
+ dump_type_prefix. */
+ break;
}
}
-/* Return a function declaration which corresponds to the IDENTIFIER_NODE
- argument. */
-
-static tree
-ident_fndecl (t)
- tree t;
-{
- tree n = lookup_name (t, 0);
-
- if (n == NULL_TREE)
- return NULL_TREE;
-
- if (TREE_CODE (n) == FUNCTION_DECL)
- return n;
- else if (TREE_CODE (n) == TREE_LIST
- && TREE_CODE (TREE_VALUE (n)) == FUNCTION_DECL)
- return TREE_VALUE (n);
-
- my_friendly_abort (66);
- return NULL_TREE;
-}
-
-#ifndef NO_DOLLAR_IN_LABEL
-# define GLOBAL_THING "_GLOBAL_$"
-#else
-# ifndef NO_DOT_IN_LABEL
-# define GLOBAL_THING "_GLOBAL_."
-# else
-# define GLOBAL_THING "_GLOBAL__"
-# endif
-#endif
-
-#define GLOBAL_IORD_P(NODE) \
- ! strncmp (IDENTIFIER_POINTER(NODE), GLOBAL_THING, sizeof (GLOBAL_THING) - 1)
-
static void
dump_global_iord (t)
tree t;
{
- char *name = IDENTIFIER_POINTER (t);
+ const char *p = NULL;
- OB_PUTS ("(static ");
- if (name [sizeof (GLOBAL_THING) - 1] == 'I')
- OB_PUTS ("initializers");
- else if (name [sizeof (GLOBAL_THING) - 1] == 'D')
- OB_PUTS ("destructors");
+ if (DECL_GLOBAL_CTOR_P (t))
+ p = "initializers";
+ else if (DECL_GLOBAL_DTOR_P (t))
+ p = "destructors";
else
- my_friendly_abort (352);
-
- OB_PUTS (" for ");
- OB_PUTCP (input_filename);
- OB_PUTC (')');
+ abort ();
+
+ output_printf (scratch_buffer, "(static %s for %s)", p, input_filename);
}
static void
-dump_simple_decl (t, type, v)
+dump_simple_decl (t, type, flags)
tree t;
tree type;
- int v;
+ int flags;
{
- if (v > 0)
+ if (flags & TFF_DECL_SPECIFIERS)
{
- 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)
+ output_add_space (scratch_buffer);
}
+ 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);
+ print_identifier (scratch_buffer, "<anonymous>");
+ if (flags & TFF_DECL_SPECIFIERS)
+ 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 */
+ int 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 & TFF_DECL_SPECIFIERS)
+ && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
/* Say `class T' not just `T'. */
- OB_PUTS ("class ");
+ output_add_string (scratch_buffer, "class ");
- dump_type (TREE_TYPE (t), v);
+ dump_type (TREE_TYPE (t), flags);
break;
}
}
- if (v > 0)
- OB_PUTS ("typedef ");
- dump_simple_decl (t, DECL_ORIGINAL_TYPE (t)
- ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), v);
+ if (flags & TFF_DECL_SPECIFIERS)
+ output_add_string (scratch_buffer, "typedef ");
+ dump_simple_decl (t, DECL_ORIGINAL_TYPE (t)
+ ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
+ flags);
break;
-
+
case VAR_DECL:
if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
{
- OB_PUTS ("vtable for ");
- if (TYPE_P (DECL_CONTEXT (t)))
- dump_type (DECL_CONTEXT (t), v);
- else
- /* This case can arise with -fno-vtable-thunks. See
- expand_upcast_fixups. It's not clear what to print
- here. */
- OB_PUTS ("{unknown type}");
+ output_add_string (scratch_buffer, "vtable for ");
+ my_friendly_assert (TYPE_P (DECL_CONTEXT (t)), 20010720);
+ dump_type (DECL_CONTEXT (t), flags);
break;
}
/* 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 RESULT_DECL:
+ output_add_string (scratch_buffer, "<return value> ");
+ 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}");
+ print_identifier (scratch_buffer, "<unnamed>");
else
- OB_PUTID (DECL_NAME (t));
+ print_tree_identifier (scratch_buffer, DECL_NAME (t));
break;
case SCOPE_REF:
- dump_decl (TREE_OPERAND (t, 0), 0);
- OB_PUTS ("::");
- dump_decl (TREE_OPERAND (t, 1), 0);
- break;
+ dump_decl (TREE_OPERAND (t, 0), flags & ~TFF_DECL_SPECIFIERS);
+ print_scope_operator (scratch_buffer);
+ dump_decl (TREE_OPERAND (t, 1), flags);
+ break;
case ARRAY_REF:
- dump_decl (TREE_OPERAND (t, 0), v);
- OB_PUTC ('[');
- dump_decl (TREE_OPERAND (t, 1), v);
- OB_PUTC (']');
+ dump_decl (TREE_OPERAND (t, 0), flags);
+ print_left_bracket (scratch_buffer);
+ dump_decl (TREE_OPERAND (t, 1), flags);
+ print_right_bracket (scratch_buffer);
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:
- my_friendly_abort (69);
+ abort ();
break;
/* These special cases are duplicated here so that other functions
- can feed identifiers to cp_error and get them demangled properly. */
+ can feed identifiers to error and get them demangled properly. */
case IDENTIFIER_NODE:
- { tree f;
- if (DESTRUCTOR_NAME_P (t)
- && (f = ident_fndecl (t))
- && DECL_LANGUAGE (f) == lang_cplusplus)
- {
- OB_PUTC ('~');
- dump_decl (DECL_NAME (f), 0);
- }
- else if (IDENTIFIER_TYPENAME_P (t))
- {
- OB_PUTS ("operator ");
- /* Not exactly IDENTIFIER_TYPE_VALUE. */
- dump_type (TREE_TYPE (t), 0);
- break;
- }
- else if (IDENTIFIER_OPNAME_P (t))
- {
- char *name_string = operator_name_string (t);
- OB_PUTS ("operator ");
- OB_PUTCP (name_string);
- }
- else
- OB_PUTID (t);
- }
+ if (IDENTIFIER_TYPENAME_P (t))
+ {
+ output_add_string (scratch_buffer, "operator ");
+ /* Not exactly IDENTIFIER_TYPE_VALUE. */
+ dump_type (TREE_TYPE (t), flags);
+ break;
+ }
+ else
+ print_tree_identifier (scratch_buffer, t);
break;
case OVERLOAD:
@@ -821,81 +931,16 @@ dump_decl (t, v)
/* Fall through. */
case FUNCTION_DECL:
- if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t)))
- dump_global_iord (DECL_ASSEMBLER_NAME (t));
+ if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
+ dump_global_iord (t);
else if (! DECL_LANG_SPECIFIC (t))
- OB_PUTS ("{internal}");
+ print_identifier (scratch_buffer, "<internal>");
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);
- }
- }
+ dump_template_decl (t, flags);
break;
case TEMPLATE_ID_EXPR:
@@ -904,207 +949,273 @@ 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);
- OB_PUTC ('<');
+ dump_decl (name, flags);
+ print_template_argument_list_start (scratch_buffer);
for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args))
{
- if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (args))) == 't'
- || TREE_CODE (TREE_VALUE (args)) == TEMPLATE_DECL)
- dump_type (TREE_VALUE (args), 0);
- else
- dump_expr (TREE_VALUE (args), 0);
+ dump_template_argument (TREE_VALUE (args), flags);
if (TREE_CHAIN (args))
- OB_PUTC2 (',', ' ');
+ separate_with_comma (scratch_buffer);
}
- OB_END_TEMPLATE_ID ();
+ print_template_argument_list_end (scratch_buffer);
}
break;
case LOOKUP_EXPR:
- dump_decl (TREE_OPERAND (t, 0), v);
+ dump_decl (TREE_OPERAND (t, 0), flags);
break;
case LABEL_DECL:
- OB_PUTID (DECL_NAME (t));
+ print_tree_identifier (scratch_buffer, DECL_NAME (t));
break;
case CONST_DECL:
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 | TFF_EXPR_IN_PARENS);
else
- OB_PUTS ("enumerator");
+ print_identifier (scratch_buffer, "enumerator");
break;
case USING_DECL:
- OB_PUTS ("using ");
- dump_type (DECL_INITIAL (t), 0);
- OB_PUTS ("::");
- OB_PUTID (DECL_NAME (t));
+ output_add_string (scratch_buffer, "using ");
+ dump_type (DECL_INITIAL (t), flags);
+ print_scope_operator (scratch_buffer);
+ print_tree_identifier (scratch_buffer, DECL_NAME (t));
break;
default:
- sorry ("`%s' not supported by dump_decl",
- tree_code_name[(int) TREE_CODE (t)]);
+ sorry_for_unsupported_tree (t);
+ /* Fallthrough to error. */
+
+ case ERROR_MARK:
+ print_identifier (scratch_buffer, "<declaration error>");
+ 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;
+ int flags;
+{
+ tree orig_parms = DECL_TEMPLATE_PARMS (t);
+ tree parms;
+ int i;
+
+ if (flags & TFF_TEMPLATE_HEADER)
+ {
+ for (parms = orig_parms = nreverse (orig_parms);
+ parms;
+ parms = TREE_CHAIN (parms))
+ {
+ tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
+ int len = TREE_VEC_LENGTH (inner_parms);
+
+ output_add_string (scratch_buffer, "template<");
+
+ /* If we've shown the template prefix, we'd better show the
+ parameters' and decl's type too. */
+ flags |= TFF_DECL_SPECIFIERS;
+
+ for (i = 0; i < len; i++)
+ {
+ if (i)
+ separate_with_comma (scratch_buffer);
+ dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags);
+ }
+ print_template_argument_list_end (scratch_buffer);
+ output_add_space (scratch_buffer);
+ }
+ nreverse(orig_parms);
+
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
+ /* Say `template<arg> class TT' not just `template<arg> TT'. */
+ output_add_string (scratch_buffer, "class ");
+ }
+
+ if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
+ dump_type (TREE_TYPE (t),
+ ((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
+ | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)));
+ else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL)
+ dump_decl (DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME);
+ else if (TREE_TYPE (t) == NULL_TREE)
+ abort ();
+ else
+ switch (NEXT_CODE (t))
+ {
+ case METHOD_TYPE:
+ case FUNCTION_TYPE:
+ dump_function_decl (t, flags | TFF_TEMPLATE_NAME);
+ break;
+ default:
+ /* This case can occur with some illegal code. */
+ dump_type (TREE_TYPE (t),
+ (flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
+ | (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 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 - -- ++
- As cp_error can only apply the '#' flag once to give 0 and 1 for V, there
+ function declaration. The TFF_ bits in FLAGS tells us how to behave.
+ As 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;
+ int flags;
{
- tree name;
tree fntype;
tree parmtypes;
tree cname = NULL_TREE;
+ tree template_args = NULL_TREE;
+ tree template_parms = NULL_TREE;
+ int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
if (TREE_CODE (t) == TEMPLATE_DECL)
t = DECL_TEMPLATE_RESULT (t);
- name = DECL_ASSEMBLER_NAME (t);
+ /* Pretty print template instantiations only. */
+ if (DECL_USE_TEMPLATE (t) && DECL_TEMPLATE_INFO (t))
+ {
+ tree tmpl;
+
+ template_args = DECL_TI_ARGS (t);
+ tmpl = most_general_template (t);
+ if (tmpl && TREE_CODE (tmpl) == TEMPLATE_DECL)
+ {
+ template_parms = DECL_TEMPLATE_PARMS (tmpl);
+ t = tmpl;
+ }
+ }
+
fntype = TREE_TYPE (t);
- parmtypes = TYPE_ARG_TYPES (fntype);
+ parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
- /* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT. */
if (DECL_CLASS_SCOPE_P (t))
- cname = DECL_CLASS_CONTEXT (t);
+ cname = DECL_CONTEXT (t);
/* this is for partially instantiated template methods */
else if (TREE_CODE (fntype) == METHOD_TYPE)
cname = TREE_TYPE (TREE_VALUE (parmtypes));
- /* Print the return type. */
- if (v > 0)
+ if (!(flags & TFF_DECL_SPECIFIERS))
+ /* OK */;
+ else if (DECL_STATIC_FUNCTION_P (t))
+ print_identifier (scratch_buffer, "static ");
+ else if (DECL_VIRTUAL_P (t))
+ print_identifier (scratch_buffer, "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), 1, 0);
- OB_PUTC (' ');
- }
+ dump_type_prefix (TREE_TYPE (fntype), flags);
+ output_add_space (scratch_buffer);
}
/* 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);
+ dump_type (cname, flags);
+ print_scope_operator (scratch_buffer);
}
- else if (CP_DECL_CONTEXT (t) != global_namespace)
+ else
+ dump_scope (CP_DECL_CONTEXT (t), flags);
+
+ dump_function_name (t, flags);
+
+ if (1)
{
- dump_decl (DECL_CONTEXT (t), 0);
- OB_PUTC2 (':',':');
- }
+ dump_parameters (parmtypes, flags);
- if (DESTRUCTOR_NAME_P (name) && DECL_LANGUAGE (t) == lang_cplusplus)
- parmtypes = TREE_CHAIN (parmtypes);
-
- dump_function_name (t);
+ if (TREE_CODE (fntype) == METHOD_TYPE)
+ dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))),
+ before);
- /* If V is negative, we don't print the argument types. */
- if (v < 0)
- return;
+ if (flags & TFF_EXCEPTION_SPECIFICATION)
+ dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags);
- dump_parameters (parmtypes, v & 1, 0);
-
- 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)
+ /* If T is a template instantiation, dump the parameter binding. */
+ if (template_parms != NULL_TREE && template_args != NULL_TREE)
{
- if (IS_SIGNATURE (cname))
- /* We look at the type pointed to by the `optr' field of `this.' */
- dump_qualifiers
- (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (TYPE_ARG_TYPES (fntype))))), before);
- else
- dump_qualifiers
- (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before);
+ output_add_string (scratch_buffer, " [with ");
+ dump_template_bindings (template_parms, template_args);
+ print_right_bracket (scratch_buffer);
}
-
- if (v >= 2)
- dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), 0);
}
-/* 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;
+ int flags;
{
int first;
- OB_PUTC ('(');
+
+ print_left_paren (scratch_buffer);
for (first = 1; parmtypes != void_list_node;
parmtypes = TREE_CHAIN (parmtypes))
{
if (!first)
- OB_PUTC2 (',', ' ');
+ separate_with_comma (scratch_buffer);
first = 0;
if (!parmtypes)
{
- OB_PUTS ("...");
+ print_identifier (scratch_buffer, "...");
break;
}
- dump_type_real (TREE_VALUE (parmtypes), 0, canonical_name);
-
- if (TREE_PURPOSE (parmtypes) && v)
+ dump_type (TREE_VALUE (parmtypes), flags);
+
+ if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes))
{
- OB_PUTS (" = ");
- dump_expr (TREE_PURPOSE (parmtypes), 0);
+ output_add_string (scratch_buffer, " = ");
+ dump_expr (TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS);
}
}
- OB_PUTC (')');
+ print_right_paren (scratch_buffer);
}
/* 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;
+ int flags;
{
if (t)
{
- OB_PUTS (" throw (");
+ output_add_string (scratch_buffer, " throw (");
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 (',', ' ');
+ separate_with_comma (scratch_buffer);
}
- OB_PUTC (')');
+ print_right_paren (scratch_buffer);
}
}
@@ -1112,15 +1223,21 @@ dump_exception_spec (t, canonical_name)
and destructors properly. */
static void
-dump_function_name (t)
+dump_function_name (t, flags)
tree t;
+ int flags;
{
tree name = DECL_NAME (t);
+ /* Don't let the user see __comp_ctor et al. */
+ if (DECL_CONSTRUCTOR_P (t)
+ || DECL_DESTRUCTOR_P (t))
+ name = constructor_name (DECL_CONTEXT (t));
+
if (DECL_DESTRUCTOR_P (t))
{
- OB_PUTC ('~');
- dump_decl (name, 0);
+ output_add_character (scratch_buffer, '~');
+ dump_decl (name, TFF_PLAIN_IDENTIFIER);
}
else if (DECL_CONV_FN_P (t))
{
@@ -1130,88 +1247,103 @@ dump_function_name (t)
declarations, both will have the same name, yet
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);
+ output_add_string (scratch_buffer, "operator ");
+ dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
}
else if (IDENTIFIER_OPNAME_P (name))
- {
- char *name_string = operator_name_string (name);
- OB_PUTS ("operator ");
- OB_PUTCP (name_string);
- }
+ print_tree_identifier (scratch_buffer, name);
else
- dump_decl (name, 0);
+ dump_decl (name, flags);
- if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t)
- && DECL_TEMPLATE_INFO (t)
- && (DECL_TEMPLATE_SPECIALIZATION (t)
+ if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
+ && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (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);
+}
+
+/* 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;
+ int flags;
+{
+ tree args = info ? TI_ARGS (info) : NULL_TREE;
+
+ if (primary && flags & TFF_TEMPLATE_NAME)
+ return;
+ flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME);
+ print_template_argument_list_start (scratch_buffer);
- /* Be careful only to print things when we have them, so as not
+ /* Be careful only to print things when we have them, so as not
to crash producing error messages. */
- if (args)
- {
- if (TREE_CODE (args) == TREE_LIST)
- {
- tree arg;
- int need_comma = 0;
-
- for (arg = args; arg; arg = TREE_CHAIN (arg))
- {
- tree a = TREE_VALUE (arg);
-
- if (need_comma)
- OB_PUTS (", ");
-
- if (a)
- {
- if (TREE_CODE_CLASS (TREE_CODE (a)) == 't'
- || TREE_CODE (a) == TEMPLATE_DECL)
- dump_type (a, 0);
- else
- dump_expr (a, 0);
- }
-
- need_comma = 1;
- }
- }
- else if (TREE_CODE (args) == TREE_VEC)
- {
- int i;
- int need_comma = 0;
-
- if (TREE_VEC_LENGTH (args) > 0
- && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
- args = TREE_VEC_ELT (args,
- TREE_VEC_LENGTH (args) - 1);
-
- for (i = 0; i < TREE_VEC_LENGTH (args); i++)
- {
- tree a = TREE_VEC_ELT (args, i);
-
- if (need_comma)
- OB_PUTS (", ");
-
- if (a)
- {
- if (TREE_CODE_CLASS (TREE_CODE (a)) == 't'
- || TREE_CODE (a) == TEMPLATE_DECL)
- dump_type (a, 0);
- else
- dump_expr (a, 0);
- }
-
- need_comma = 1;
- }
- }
- }
- OB_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)
+ separate_with_comma (scratch_buffer);
+
+ if (!arg)
+ print_identifier (scratch_buffer, "<template parameter error>");
+ else
+ dump_template_argument (arg, flags);
+ need_comma = 1;
+ }
+ }
+ 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)
+ separate_with_comma (scratch_buffer);
+
+ dump_decl (parm, flags & ~TFF_DECL_SPECIFIERS);
+ }
}
+ print_template_argument_list_end (scratch_buffer);
}
static void
@@ -1221,42 +1353,42 @@ dump_char (c)
switch (c)
{
case TARGET_NEWLINE:
- OB_PUTS ("\\n");
+ output_add_string (scratch_buffer, "\\n");
break;
case TARGET_TAB:
- OB_PUTS ("\\t");
+ output_add_string (scratch_buffer, "\\t");
break;
case TARGET_VT:
- OB_PUTS ("\\v");
+ output_add_string (scratch_buffer, "\\v");
break;
case TARGET_BS:
- OB_PUTS ("\\b");
+ output_add_string (scratch_buffer, "\\b");
break;
case TARGET_CR:
- OB_PUTS ("\\r");
+ output_add_string (scratch_buffer, "\\r");
break;
case TARGET_FF:
- OB_PUTS ("\\f");
+ output_add_string (scratch_buffer, "\\f");
break;
case TARGET_BELL:
- OB_PUTS ("\\a");
+ output_add_string (scratch_buffer, "\\a");
break;
case '\\':
- OB_PUTS ("\\\\");
+ output_add_string (scratch_buffer, "\\\\");
break;
case '\'':
- OB_PUTS ("\\'");
+ output_add_string (scratch_buffer, "\\'");
break;
case '\"':
- OB_PUTS ("\\\"");
+ output_add_string (scratch_buffer, "\\\"");
break;
default:
if (ISPRINT (c))
- OB_PUTC (c);
+ output_add_character (scratch_buffer, c);
else
{
sprintf (digit_buffer, "\\%03o", (int) c);
- OB_PUTCP (digit_buffer);
+ output_add_string (scratch_buffer, digit_buffer);
}
}
}
@@ -1264,24 +1396,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;
+ int flags;
{
while (l)
{
- dump_expr (TREE_VALUE (l), 0);
- if (TREE_CHAIN (l))
- OB_PUTC2 (',', ' ');
+ dump_expr (TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS);
l = TREE_CHAIN (l);
+ if (l)
+ separate_with_comma (scratch_buffer);
}
}
-/* 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 */
+ int flags;
{
switch (TREE_CODE (t))
{
@@ -1292,7 +1425,8 @@ dump_expr (t, nop)
case FUNCTION_DECL:
case TEMPLATE_DECL:
case NAMESPACE_DECL:
- dump_decl (t, -1);
+ case OVERLOAD:
+ dump_decl (t, flags & ~TFF_DECL_SPECIFIERS);
break;
case INTEGER_CST:
@@ -1303,47 +1437,65 @@ dump_expr (t, nop)
/* If it's an enum, output its tag, rather than its value. */
if (TREE_CODE (type) == ENUMERAL_TYPE)
{
- char *p = enum_name_string (t, type);
- OB_PUTCP (p);
+ tree values = TYPE_VALUES (type);
+
+ for (; values;
+ values = TREE_CHAIN (values))
+ if (tree_int_cst_equal (TREE_VALUE (values), t))
+ break;
+
+ if (values)
+ print_tree_identifier (scratch_buffer, TREE_PURPOSE (values));
+ else
+ {
+ /* Value must have been cast. */
+ print_left_paren (scratch_buffer);
+ dump_type (type, flags);
+ print_right_paren (scratch_buffer);
+ goto do_int;
+ }
}
else if (type == boolean_type_node)
{
- if (t == boolean_false_node
- || (TREE_INT_CST_LOW (t) == 0
- && TREE_INT_CST_HIGH (t) == 0))
- OB_PUTS ("false");
+ if (t == boolean_false_node || integer_zerop (t))
+ print_identifier (scratch_buffer, "false");
else if (t == boolean_true_node)
- OB_PUTS ("true");
+ print_identifier (scratch_buffer, "true");
}
else if (type == char_type_node)
{
- OB_PUTC ('\'');
- dump_char (TREE_INT_CST_LOW (t));
- OB_PUTC ('\'');
+ output_add_character (scratch_buffer, '\'');
+ dump_char (tree_low_cst (t, 0));
+ output_add_character (scratch_buffer, '\'');
}
- else if (TREE_INT_CST_HIGH (t)
- != (TREE_INT_CST_LOW (t) >> (HOST_BITS_PER_WIDE_INT - 1)))
+ else
{
- tree val = t;
- if (TREE_INT_CST_HIGH (val) < 0)
+ do_int:
+ if (! host_integerp (t, 0))
{
- OB_PUTC ('-');
- val = build_int_2 (~TREE_INT_CST_LOW (val),
- -TREE_INT_CST_HIGH (val));
+ tree val = t;
+
+ if (tree_int_cst_sgn (val) < 0)
+ {
+ output_add_character (scratch_buffer, '-');
+ val = build_int_2 (-TREE_INT_CST_LOW (val),
+ ~TREE_INT_CST_HIGH (val)
+ + !TREE_INT_CST_LOW (val));
+ }
+ /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
+ systems? */
+ {
+ static char format[10]; /* "%x%09999x\0" */
+ if (!format[0])
+ sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
+ sprintf (digit_buffer, format, TREE_INT_CST_HIGH (val),
+ TREE_INT_CST_LOW (val));
+ output_add_string (scratch_buffer, digit_buffer);
+ }
}
- /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
- systems? */
- {
- static char format[10]; /* "%x%09999x\0" */
- if (!format[0])
- sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
- sprintf (digit_buffer, format, TREE_INT_CST_HIGH (val),
- TREE_INT_CST_LOW (val));
- OB_PUTCP (digit_buffer);
- }
+ else
+ print_integer (scratch_buffer, TREE_INT_CST_LOW (t));
}
- else
- OB_PUTI (TREE_INT_CST_LOW (t));
}
break;
@@ -1352,75 +1504,96 @@ dump_expr (t, nop)
sprintf (digit_buffer, "%g", TREE_REAL_CST (t));
#else
{
- unsigned char *p = (unsigned char *) &TREE_REAL_CST (t);
+ const unsigned char *p = (const unsigned char *) &TREE_REAL_CST (t);
size_t i;
strcpy (digit_buffer, "0x");
for (i = 0; i < sizeof TREE_REAL_CST (t); i++)
sprintf (digit_buffer + 2 + 2*i, "%02x", *p++);
}
#endif
- OB_PUTCP (digit_buffer);
+ output_add_string (scratch_buffer, digit_buffer);
break;
case PTRMEM_CST:
- OB_PUTC ('&');
- dump_type (PTRMEM_CST_CLASS (t), 0);
- OB_PUTS ("::");
- OB_PUTID (DECL_NAME (PTRMEM_CST_MEMBER (t)));
+ output_add_character (scratch_buffer, '&');
+ dump_type (PTRMEM_CST_CLASS (t), flags);
+ print_scope_operator (scratch_buffer);
+ print_tree_identifier
+ (scratch_buffer, DECL_NAME (PTRMEM_CST_MEMBER (t)));
break;
case STRING_CST:
{
- char *p = TREE_STRING_POINTER (t);
+ const char *p = TREE_STRING_POINTER (t);
int len = TREE_STRING_LENGTH (t) - 1;
int i;
- OB_PUTC ('\"');
+ output_add_character (scratch_buffer, '\"');
for (i = 0; i < len; i++)
dump_char (p[i]);
- OB_PUTC ('\"');
+ output_add_character (scratch_buffer, '\"');
}
break;
case COMPOUND_EXPR:
- dump_binary_op (",", t);
+ print_left_paren (scratch_buffer);
+ dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ separate_with_comma (scratch_buffer);
+ dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ print_right_paren (scratch_buffer);
break;
case COND_EXPR:
- OB_PUTC ('(');
- dump_expr (TREE_OPERAND (t, 0), 0);
- OB_PUTS (" ? ");
- dump_expr (TREE_OPERAND (t, 1), 0);
- OB_PUTS (" : ");
- dump_expr (TREE_OPERAND (t, 2), 0);
- OB_PUTC (')');
+ print_left_paren (scratch_buffer);
+ dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ output_add_string (scratch_buffer, " ? ");
+ dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ output_add_string (scratch_buffer, " : ");
+ dump_expr (TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS);
+ print_right_paren (scratch_buffer);
break;
case SAVE_EXPR:
if (TREE_HAS_CONSTRUCTOR (t))
{
- OB_PUTS ("new ");
- dump_type (TREE_TYPE (TREE_TYPE (t)), 0);
+ output_add_string (scratch_buffer, "new ");
+ dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
}
else
{
- dump_expr (TREE_OPERAND (t, 0), 0);
+ dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
}
break;
case AGGR_INIT_EXPR:
- OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t)));
- OB_PUTC ('(');
+ {
+ tree fn = NULL_TREE;
+
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
+ fn = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
+
+ if (fn && TREE_CODE (fn) == FUNCTION_DECL)
+ {
+ if (DECL_CONSTRUCTOR_P (fn))
+ print_tree_identifier
+ (scratch_buffer, TYPE_IDENTIFIER (TREE_TYPE (t)));
+ else
+ dump_decl (fn, 0);
+ }
+ else
+ dump_expr (TREE_OPERAND (t, 0), 0);
+ }
+ print_left_paren (scratch_buffer);
if (TREE_OPERAND (t, 1))
- dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
- OB_PUTC (')');
+ dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
+ print_right_paren (scratch_buffer);
break;
case CALL_EXPR:
{
tree fn = TREE_OPERAND (t, 0);
tree args = TREE_OPERAND (t, 1);
-
+
if (TREE_CODE (fn) == ADDR_EXPR)
fn = TREE_OPERAND (fn, 0);
@@ -1429,21 +1602,21 @@ dump_expr (t, nop)
tree ob = TREE_VALUE (args);
if (TREE_CODE (ob) == ADDR_EXPR)
{
- dump_expr (TREE_OPERAND (ob, 0), 0);
- OB_PUTC ('.');
+ dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
+ output_add_character (scratch_buffer, '.');
}
else if (TREE_CODE (ob) != PARM_DECL
|| strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
{
- dump_expr (ob, 0);
- OB_PUTC2 ('-', '>');
+ dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
+ output_add_string (scratch_buffer, "->");
}
args = TREE_CHAIN (args);
}
- dump_expr (fn, 0);
- OB_PUTC ('(');
- dump_expr_list (args);
- OB_PUTC (')');
+ dump_expr (fn, flags | TFF_EXPR_IN_PARENS);
+ print_left_paren (scratch_buffer);
+ dump_expr_list (args, flags);
+ print_right_paren (scratch_buffer);
}
break;
@@ -1451,25 +1624,26 @@ dump_expr (t, nop)
{
tree type = TREE_OPERAND (t, 1);
if (NEW_EXPR_USE_GLOBAL (t))
- OB_PUTS ("::");
- OB_PUTS ("new ");
+ print_scope_operator (scratch_buffer);
+ output_add_string (scratch_buffer, "new ");
if (TREE_OPERAND (t, 0))
{
- OB_PUTC ('(');
- dump_expr_list (TREE_OPERAND (t, 0));
- OB_PUTS (") ");
+ print_left_paren (scratch_buffer);
+ dump_expr_list (TREE_OPERAND (t, 0), flags);
+ output_add_string (scratch_buffer, ") ");
}
if (TREE_CODE (type) == ARRAY_REF)
type = build_cplus_array_type
(TREE_OPERAND (type, 0),
- build_index_type (size_binop (MINUS_EXPR, TREE_OPERAND (type, 1),
- integer_one_node)));
- dump_type (type, 0);
+ build_index_type (fold (build (MINUS_EXPR, integer_type_node,
+ TREE_OPERAND (type, 1),
+ integer_one_node))));
+ dump_type (type, flags);
if (TREE_OPERAND (t, 2))
{
- OB_PUTC ('(');
- dump_expr_list (TREE_OPERAND (t, 2));
- OB_PUTC (')');
+ print_left_paren (scratch_buffer);
+ dump_expr_list (TREE_OPERAND (t, 2), flags);
+ print_right_paren (scratch_buffer);
}
}
break;
@@ -1481,9 +1655,10 @@ 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 | TFF_EXPR_IN_PARENS);
break;
+ case INIT_EXPR:
case MODIFY_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
@@ -1506,19 +1681,20 @@ dump_expr (t, nop)
case GE_EXPR:
case EQ_EXPR:
case NE_EXPR:
- dump_binary_op (opname_tab[(int) TREE_CODE (t)], t);
+ case EXACT_DIV_EXPR:
+ dump_binary_op (operator_name_info[(int) TREE_CODE (t)].name, 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:
@@ -1530,36 +1706,49 @@ 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 | TFF_EXPR_IN_PARENS);
+ output_add_string (scratch_buffer, "->");
}
}
else
{
- dump_expr (ob, 0);
- OB_PUTC ('.');
+ dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
+ output_add_character (scratch_buffer, '.');
}
- dump_expr (TREE_OPERAND (t, 1), 1);
+ dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
}
break;
case ARRAY_REF:
- dump_expr (TREE_OPERAND (t, 0), 0);
- OB_PUTC ('[');
- dump_expr (TREE_OPERAND (t, 1), 0);
- OB_PUTC (']');
+ dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ print_left_bracket (scratch_buffer);
+ dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ print_right_bracket (scratch_buffer);
break;
case CONVERT_EXPR:
- dump_unary_op ("+", t, nop);
+ if (VOID_TYPE_P (TREE_TYPE (t)))
+ {
+ print_left_paren (scratch_buffer);
+ dump_type (TREE_TYPE (t), flags);
+ print_right_paren (scratch_buffer);
+ dump_expr (TREE_OPERAND (t, 0), flags);
+ }
+ else
+ 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);
+ || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST
+ /* An ADDR_EXPR can have reference type. In that case, we
+ shouldn't print the `&' doing so indicates to the user
+ that the expression has pointer type. */
+ || (TREE_TYPE (t)
+ && TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE))
+ dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
else
- dump_unary_op ("&", t, nop);
+ dump_unary_op ("&", t, flags);
break;
case INDIRECT_REF:
@@ -1567,19 +1756,19 @@ 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);
- OB_PUTC ('(');
- dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)));
- OB_PUTC (')');
+ dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ print_left_paren (scratch_buffer);
+ dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
+ print_right_paren (scratch_buffer);
}
else
{
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,15 +1777,16 @@ 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 (operator_name_info [(int)TREE_CODE (t)].name, t, flags);
break;
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
- OB_PUTC ('(');
- dump_expr (TREE_OPERAND (t, 0), 0);
- OB_PUTCP (opname_tab[(int)TREE_CODE (t)]);
- OB_PUTC (')');
+ print_left_paren (scratch_buffer);
+ dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ print_identifier
+ (scratch_buffer, operator_name_info[(int)TREE_CODE (t)].name);
+ print_right_paren (scratch_buffer);
break;
case NON_LVALUE_EXPR:
@@ -1609,55 +1799,53 @@ dump_expr (t, nop)
while (TREE_CODE (next) == POINTER_TYPE)
next = TREE_TYPE (next);
-
+
if (TREE_CODE (next) == FUNCTION_TYPE)
{
- if (!nop) OB_PUTC ('(');
- OB_PUTC ('*');
- dump_expr (TREE_OPERAND (t, 0), 1);
- if (!nop) OB_PUTC (')');
+ if (flags & TFF_EXPR_IN_PARENS)
+ print_left_paren (scratch_buffer);
+ output_add_character (scratch_buffer, '*');
+ dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ if (flags & TFF_EXPR_IN_PARENS)
+ print_right_paren (scratch_buffer);
break;
}
/* else FALLTHRU */
}
- dump_expr (TREE_OPERAND (t, 0), 0);
+ dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
break;
case NOP_EXPR:
- dump_expr (TREE_OPERAND (t, 0), nop);
+ dump_expr (TREE_OPERAND (t, 0), flags);
+ break;
+
+ case EXPR_WITH_FILE_LOCATION:
+ dump_expr (EXPR_WFL_NODE (t), flags);
break;
case CONSTRUCTOR:
if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
{
- tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0);
+ tree idx = build_component_ref (t, pfn_identifier, NULL_TREE, 0);
- if (integer_all_onesp (idx))
- {
- tree pfn = PFN_FROM_PTRMEMFUNC (t);
- dump_unary_op ("&", pfn, 0);
- break;
- }
- else if (TREE_CODE (idx) == INTEGER_CST
- && tree_int_cst_equal (idx, integer_zero_node))
+ if (integer_zerop (idx))
{
/* A NULL pointer-to-member constant. */
- OB_PUTS ("((");
- dump_type (TREE_TYPE (t), 0);
- OB_PUTS (") 0)");
+ output_add_string (scratch_buffer, "((");
+ dump_type (TREE_TYPE (t), flags);
+ output_add_string (scratch_buffer, ") 0)");
break;
}
- else if (TREE_CODE (idx) == INTEGER_CST
- && TREE_INT_CST_HIGH (idx) == 0)
+ else if (host_integerp (idx, 0))
{
tree virtuals;
unsigned HOST_WIDE_INT n;
t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t)));
t = TYPE_METHOD_BASETYPE (t);
- virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t)));
-
- n = TREE_INT_CST_LOW (idx);
+ virtuals = TYPE_BINFO_VIRTUALS (TYPE_MAIN_VARIANT (t));
+
+ n = tree_low_cst (idx, 0);
/* Map vtable index back one, to allow for the null pointer to
member. */
@@ -1670,14 +1858,15 @@ dump_expr (t, nop)
}
if (virtuals)
{
- dump_expr (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
+ dump_expr (BV_FN (virtuals),
+ flags | TFF_EXPR_IN_PARENS);
break;
}
}
}
- OB_PUTC ('{');
- dump_expr_list (CONSTRUCTOR_ELTS (t));
- OB_PUTC ('}');
+ output_add_character (scratch_buffer, '{');
+ dump_expr_list (CONSTRUCTOR_ELTS (t), flags);
+ output_add_character (scratch_buffer, '}');
break;
case OFFSET_REF:
@@ -1688,268 +1877,287 @@ 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 | TFF_EXPR_IN_PARENS);
else if (BASELINK_P (t))
- dump_expr (OVL_CURRENT (TREE_VALUE (t)), 0);
+ dump_expr (OVL_CURRENT (TREE_VALUE (t)), flags | TFF_EXPR_IN_PARENS);
else
- dump_decl (t, 0);
+ dump_decl (t, flags);
}
else
{
if (TREE_CODE (ob) == INDIRECT_REF)
{
- dump_expr (TREE_OPERAND (ob, 0), 0);
- OB_PUTS (" ->* ");
+ dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
+ output_add_string (scratch_buffer, "->*");
}
else
{
- dump_expr (ob, 0);
- OB_PUTS (" .* ");
+ dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
+ output_add_string (scratch_buffer, ".*");
}
- dump_expr (TREE_OPERAND (t, 1), 0);
+ dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
}
break;
}
case TEMPLATE_PARM_INDEX:
- dump_decl (TEMPLATE_PARM_DECL (t), -1);
+ dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
break;
case IDENTIFIER_NODE:
- OB_PUTID (t);
+ print_tree_identifier (scratch_buffer, t);
break;
case SCOPE_REF:
- dump_type (TREE_OPERAND (t, 0), 0);
- OB_PUTS ("::");
- dump_expr (TREE_OPERAND (t, 1), 0);
+ dump_type (TREE_OPERAND (t, 0), flags);
+ print_scope_operator (scratch_buffer);
+ dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
break;
case CAST_EXPR:
if (TREE_OPERAND (t, 0) == NULL_TREE
|| TREE_CHAIN (TREE_OPERAND (t, 0)))
{
- dump_type (TREE_TYPE (t), 0);
- OB_PUTC ('(');
- dump_expr_list (TREE_OPERAND (t, 0));
- OB_PUTC (')');
+ dump_type (TREE_TYPE (t), flags);
+ print_left_paren (scratch_buffer);
+ dump_expr_list (TREE_OPERAND (t, 0), flags);
+ print_right_paren (scratch_buffer);
}
else
{
- OB_PUTC ('(');
- dump_type (TREE_TYPE (t), 0);
- OB_PUTC (')');
- OB_PUTC ('(');
- dump_expr_list (TREE_OPERAND (t, 0));
- OB_PUTC (')');
+ print_left_paren (scratch_buffer);
+ dump_type (TREE_TYPE (t), flags);
+ output_add_string (scratch_buffer, ")(");
+ dump_expr_list (TREE_OPERAND (t, 0), flags);
+ print_right_paren (scratch_buffer);
}
break;
+ case STATIC_CAST_EXPR:
+ output_add_string (scratch_buffer, "static_cast<");
+ goto cast;
+ case REINTERPRET_CAST_EXPR:
+ output_add_string (scratch_buffer, "reinterpret_cast<");
+ goto cast;
+ case CONST_CAST_EXPR:
+ output_add_string (scratch_buffer, "const_cast<");
+ goto cast;
+ case DYNAMIC_CAST_EXPR:
+ output_add_string (scratch_buffer, "dynamic_cast<");
+ cast:
+ dump_type (TREE_TYPE (t), flags);
+ output_add_string (scratch_buffer, ">(");
+ dump_expr (TREE_OPERAND (t, 0), flags);
+ print_right_paren (scratch_buffer);
+ break;
+
case LOOKUP_EXPR:
- OB_PUTID (TREE_OPERAND (t, 0));
+ print_tree_identifier (scratch_buffer, TREE_OPERAND (t, 0));
break;
case ARROW_EXPR:
- dump_expr (TREE_OPERAND (t, 0), nop);
- OB_PUTS ("->");
+ dump_expr (TREE_OPERAND (t, 0), flags);
+ output_add_string (scratch_buffer, "->");
break;
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
if (TREE_CODE (t) == SIZEOF_EXPR)
- OB_PUTS ("sizeof (");
- else
+ output_add_string (scratch_buffer, "sizeof (");
+ else
{
my_friendly_assert (TREE_CODE (t) == ALIGNOF_EXPR, 0);
- OB_PUTS ("__alignof__ (");
+ output_add_string (scratch_buffer, "__alignof__ (");
}
- if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't')
- dump_type (TREE_OPERAND (t, 0), 0);
+ if (TYPE_P (TREE_OPERAND (t, 0)))
+ dump_type (TREE_OPERAND (t, 0), flags);
else
- dump_unary_op ("*", t, 0);
- OB_PUTC (')');
+ dump_unary_op ("*", t, flags | TFF_EXPR_IN_PARENS);
+ print_right_paren (scratch_buffer);
break;
case DEFAULT_ARG:
- OB_PUTS ("{unparsed}");
+ print_identifier (scratch_buffer, "<unparsed>");
break;
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), flags);
+ output_add_character (scratch_buffer, '.');
+ dump_type (TREE_OPERAND (t, 0), flags);
+ output_add_string (scratch_buffer, "::~");
+ dump_type (TREE_OPERAND (t, 1), flags);
break;
case TEMPLATE_ID_EXPR:
- dump_decl (t, 0);
+ dump_decl (t, flags);
+ break;
+
+ case STMT_EXPR:
+ /* We don't yet have a way of dumping statements in a
+ human-readable format. */
+ output_add_string (scratch_buffer, "({...})");
+ break;
+
+ case BIND_EXPR:
+ output_add_character (scratch_buffer, '{');
+ dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
+ output_add_character (scratch_buffer, '}');
+ break;
+
+ case LOOP_EXPR:
+ output_add_string (scratch_buffer, "while (1) { ");
+ dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ output_add_character (scratch_buffer, '}');
+ break;
+
+ case EXIT_EXPR:
+ output_add_string (scratch_buffer, "if (");
+ dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ output_add_string (scratch_buffer, ") break; ");
break;
case TREE_LIST:
if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
{
- OB_PUTID (DECL_NAME (TREE_VALUE (t)));
+ print_tree_identifier (scratch_buffer, DECL_NAME (TREE_VALUE (t)));
break;
}
- /* else fall through */
+ /* else fall through */
/* This list is incomplete, but should suffice for now.
It is very important that `sorry' does not call
`report_error_function'. That could cause an infinite loop. */
default:
- sorry ("`%s' not supported by dump_expr",
- tree_code_name[(int) TREE_CODE (t)]);
-
+ sorry_for_unsupported_tree (t);
/* fall through to ERROR_MARK... */
case ERROR_MARK:
- OB_PUTCP ("{error}");
+ print_identifier (scratch_buffer, "<expression error>");
break;
}
}
static void
-dump_binary_op (opstring, t)
- char *opstring;
+dump_binary_op (opstring, t, flags)
+ const char *opstring;
tree t;
+ int flags;
{
- OB_PUTC ('(');
- dump_expr (TREE_OPERAND (t, 0), 1);
- OB_PUTC (' ');
- OB_PUTCP (opstring);
- OB_PUTC (' ');
- dump_expr (TREE_OPERAND (t, 1), 1);
- OB_PUTC (')');
+ print_left_paren (scratch_buffer);
+ dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ output_add_space (scratch_buffer);
+ if (opstring)
+ print_identifier (scratch_buffer, opstring);
+ else
+ print_identifier (scratch_buffer, "<unknown operator>");
+ output_add_space (scratch_buffer);
+ dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ print_right_paren (scratch_buffer);
}
static void
-dump_unary_op (opstring, t, nop)
- char *opstring;
+dump_unary_op (opstring, t, flags)
+ const char *opstring;
tree t;
- int nop;
+ int flags;
{
- if (!nop) OB_PUTC ('(');
- OB_PUTCP (opstring);
- dump_expr (TREE_OPERAND (t, 0), 1);
- if (!nop) OB_PUTC (')');
+ if (flags & TFF_EXPR_IN_PARENS)
+ print_left_paren (scratch_buffer);
+ print_identifier (scratch_buffer, opstring);
+ dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ if (flags & TFF_EXPR_IN_PARENS)
+ print_right_paren (scratch_buffer);
}
-/* Print a function decl with exception specification included. */
+/* Exported interface to stringifying types, exprs and decls under TFF_*
+ control. */
-char *
-fndecl_as_string (fndecl, print_default_args_p)
- tree fndecl;
- int print_default_args_p;
+const char *
+type_as_string (typ, flags)
+ tree typ;
+ int flags;
{
- OB_INIT ();
+ reinit_global_formatting_buffer ();
- dump_function_decl (fndecl, 2 + print_default_args_p);
-
- OB_FINISH ();
+ dump_type (typ, flags);
- return (char *)obstack_base (&scratch_obstack);
+ return output_finalize_message (scratch_buffer);
}
-/* 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. */
-
-char *
-type_as_string_real (typ, v, canonical_name)
- tree typ;
- int v;
- int canonical_name;
+const char *
+expr_as_string (decl, flags)
+ tree decl;
+ int flags;
{
- OB_INIT ();
-
- dump_type_real (typ, v, canonical_name);
-
- OB_FINISH ();
-
- return (char *)obstack_base (&scratch_obstack);
-}
+ reinit_global_formatting_buffer ();
+ dump_expr (decl, flags);
-char *
-type_as_string (typ, v)
- tree typ;
- int v;
-{
- return type_as_string_real (typ, v, 0);
+ return output_finalize_message (scratch_buffer);
}
-char *
-expr_as_string (decl, v)
+const char *
+decl_as_string (decl, flags)
tree decl;
- int v ATTRIBUTE_UNUSED;
+ int flags;
{
- OB_INIT ();
+ reinit_global_formatting_buffer ();
- dump_expr (decl, 1);
+ dump_decl (decl, flags);
- OB_FINISH ();
-
- return (char *)obstack_base (&scratch_obstack);
+ return output_finalize_message (scratch_buffer);
}
-/* A cross between type_as_string and fndecl_as_string.
- Only called from substitute_nice_name. */
-
-char *
-decl_as_string (decl, v)
- tree decl;
- int v;
+const char *
+context_as_string (context, flags)
+ tree context;
+ int flags;
{
- OB_INIT ();
+ reinit_global_formatting_buffer ();
- dump_decl (decl, v);
+ dump_scope (context, flags);
- OB_FINISH ();
-
- return (char *)obstack_base (&scratch_obstack);
+ return output_finalize_message (scratch_buffer);
}
/* Generate the three forms of printable names for lang_printable_name. */
-char *
+const char *
lang_decl_name (decl, v)
tree decl;
int v;
{
if (v >= 2)
- return decl_as_string (decl, 1);
+ return decl_as_string (decl, TFF_DECL_SPECIFIERS);
- OB_INIT ();
+ reinit_global_formatting_buffer ();
if (v == 1 && DECL_CLASS_SCOPE_P (decl))
{
- tree cname;
- if (TREE_CODE (decl) == FUNCTION_DECL)
- cname = DECL_CLASS_CONTEXT (decl);
- else
- cname = DECL_CONTEXT (decl);
- dump_type (cname, 0);
- OB_PUTC2 (':', ':');
+ dump_type (CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER);
+ print_scope_operator (scratch_buffer);
}
if (TREE_CODE (decl) == FUNCTION_DECL)
- dump_function_name (decl);
+ dump_function_name (decl, TFF_PLAIN_IDENTIFIER);
else
- dump_decl (DECL_NAME (decl), 0);
+ dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
- OB_FINISH ();
-
- return (char *)obstack_base (&scratch_obstack);
+ return output_finalize_message (scratch_buffer);
}
-
-char *
+const char *
cp_file_of (t)
tree t;
{
if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
return DECL_SOURCE_FILE (DECL_CONTEXT (t));
- else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
+ else if (TYPE_P (t))
return DECL_SOURCE_FILE (TYPE_MAIN_DECL (t));
else if (TREE_CODE (t) == OVERLOAD)
return DECL_SOURCE_FILE (OVL_FUNCTION (t));
@@ -1968,7 +2176,7 @@ cp_line_of (t)
&& TYPE_MAIN_DECL (TREE_TYPE (t)))
t = TREE_TYPE (t);
- if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
+ if (TYPE_P (t))
line = DECL_SOURCE_LINE (TYPE_MAIN_DECL (t));
else if (TREE_CODE (t) == OVERLOAD)
line = DECL_SOURCE_LINE (OVL_FUNCTION (t));
@@ -1981,16 +2189,73 @@ cp_line_of (t)
return line;
}
-char *
-code_as_string (c, v)
+/* Now the interfaces from error et al to dump_type et al. Each takes an
+ on/off VERBOSE flag and supply the appropriate TFF_ flags to a dump_
+ function. */
+
+static const char *
+decl_to_string (decl, verbose)
+ tree decl;
+ int verbose;
+{
+ int flags = 0;
+
+ if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == RECORD_TYPE
+ || TREE_CODE (decl) == UNION_TYPE || TREE_CODE (decl) == ENUMERAL_TYPE)
+ flags = TFF_CLASS_KEY_OR_ENUM;
+ if (verbose)
+ flags |= TFF_DECL_SPECIFIERS | TFF_FUNCTION_DEFAULT_ARGUMENTS;
+ else if (TREE_CODE (decl) == FUNCTION_DECL)
+ flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE;
+ flags |= TFF_TEMPLATE_HEADER;
+
+ reinit_global_formatting_buffer ();
+
+ dump_decl (decl, flags);
+
+ return output_finalize_message (scratch_buffer);
+}
+
+static const char *
+expr_to_string (decl, verbose)
+ tree decl;
+ int verbose ATTRIBUTE_UNUSED;
+{
+ reinit_global_formatting_buffer ();
+
+ dump_expr (decl, 0);
+
+ return output_finalize_message (scratch_buffer);
+}
+
+static const char *
+fndecl_to_string (fndecl, verbose)
+ tree fndecl;
+ int verbose;
+{
+ int flags;
+
+ flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS;
+ if (verbose)
+ flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS;
+ reinit_global_formatting_buffer ();
+
+ dump_decl (fndecl, flags);
+
+ return output_finalize_message (scratch_buffer);
+}
+
+
+static const char *
+code_to_string (c, v)
enum tree_code c;
int v ATTRIBUTE_UNUSED;
{
return tree_code_name [c];
}
-char *
-language_as_string (c, v)
+const char *
+language_to_string (c, v)
enum languages c;
int v ATTRIBUTE_UNUSED;
{
@@ -2006,15 +2271,15 @@ language_as_string (c, v)
return "Java";
default:
- my_friendly_abort (355);
+ abort ();
return 0;
}
}
/* Return the proper printed version of a parameter to a C++ function. */
-char *
-parm_as_string (p, v)
+static const char *
+parm_to_string (p, v)
int p;
int v ATTRIBUTE_UNUSED;
{
@@ -2025,69 +2290,453 @@ parm_as_string (p, v)
return digit_buffer;
}
-char *
-op_as_string (p, v)
+static const char *
+op_to_string (p, v)
enum tree_code p;
int v ATTRIBUTE_UNUSED;
{
- static char buf[] = "operator ";
+ tree id;
+
+ id = operator_name_info[(int) p].identifier;
+ return id ? IDENTIFIER_POINTER (id) : "{unknown}";
+}
+
+static const char *
+type_to_string (typ, verbose)
+ tree typ;
+ int verbose;
+{
+ int flags;
- if (p == 0)
- return "{unknown}";
-
- strcpy (buf + 9, opname_tab [p]);
- return buf;
+ flags = 0;
+ if (verbose)
+ flags |= TFF_CLASS_KEY_OR_ENUM;
+ flags |= TFF_TEMPLATE_HEADER;
+
+ reinit_global_formatting_buffer ();
+
+ dump_type (typ, flags);
+
+ return output_finalize_message (scratch_buffer);
}
-char *
-assop_as_string (p, v)
+static const char *
+assop_to_string (p, v)
enum tree_code p;
int v ATTRIBUTE_UNUSED;
{
- static char buf[] = "operator ";
+ tree id;
- if (p == 0)
- return "{unknown}";
-
- strcpy (buf + 9, assignop_tab [p]);
- return buf;
+ id = assignment_operator_name_info[(int) p].identifier;
+ return id ? IDENTIFIER_POINTER (id) : "{unknown}";
}
-char *
-args_as_string (p, v)
+static const char *
+args_to_string (p, verbose)
tree p;
- int v;
+ int verbose;
{
+ int flags = 0;
+ if (verbose)
+ flags |= TFF_CLASS_KEY_OR_ENUM;
+
if (p == NULL_TREE)
return "";
- if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (p))) == 't')
- return type_as_string (p, v);
+ if (TYPE_P (TREE_VALUE (p)))
+ return type_as_string (p, flags);
- OB_INIT ();
+ reinit_global_formatting_buffer ();
for (; p; p = TREE_CHAIN (p))
{
if (TREE_VALUE (p) == null_node)
- OB_PUTS ("NULL");
+ print_identifier (scratch_buffer, "NULL");
else
- dump_type (error_type (TREE_VALUE (p)), v);
+ dump_type (error_type (TREE_VALUE (p)), flags);
if (TREE_CHAIN (p))
- OB_PUTS (", ");
+ separate_with_comma (scratch_buffer);
}
- OB_FINISH ();
- return (char *)obstack_base (&scratch_obstack);
+ return output_finalize_message (scratch_buffer);
}
-char *
-cv_as_string (p, v)
+static const char *
+cv_to_string (p, v)
tree p;
- int v ATTRIBUTE_UNUSED;
+ int v;
+{
+ reinit_global_formatting_buffer ();
+
+ dump_qualifiers (p, v ? before : none);
+
+ return output_finalize_message (scratch_buffer);
+}
+
+static void
+lang_print_error_function (context, file)
+ diagnostic_context *context;
+ const char *file;
+{
+ output_state os;
+
+ default_print_error_function (context, file);
+ os = output_buffer_state (context);
+ output_set_prefix ((output_buffer *)context, file);
+ maybe_print_instantiation_context ((output_buffer *)context);
+ output_buffer_state (context) = os;
+}
+
+static void
+cp_diagnostic_starter (buffer, dc)
+ output_buffer *buffer;
+ diagnostic_context *dc;
+{
+ report_problematic_module (buffer);
+ cp_print_error_function (buffer, dc);
+ maybe_print_instantiation_context (buffer);
+ output_set_prefix (buffer,
+ context_as_prefix (diagnostic_file_location (dc),
+ diagnostic_line_location (dc),
+ diagnostic_is_warning (dc)));
+}
+
+static void
+cp_diagnostic_finalizer (buffer, dc)
+ output_buffer *buffer;
+ diagnostic_context *dc __attribute__ ((__unused__));
+{
+ output_destroy_prefix (buffer);
+}
+
+/* Print current function onto BUFFER, in the process of reporting
+ a diagnostic message. Called from cp_diagnostic_starter. */
+static void
+cp_print_error_function (buffer, dc)
+ output_buffer *buffer;
+ diagnostic_context *dc;
+{
+ if (error_function_changed ())
+ {
+ char *prefix = diagnostic_file_location (dc)
+ ? file_name_as_prefix (diagnostic_file_location (dc))
+ : NULL;
+ output_state os;
+
+ os = output_buffer_state (buffer);
+ output_set_prefix (buffer, prefix);
+
+ if (current_function_decl == NULL)
+ output_add_string (buffer, "At global scope:");
+ else
+ output_printf
+ (buffer, "In %s `%s':", function_category (current_function_decl),
+ (*decl_printable_name) (current_function_decl, 2));
+ output_add_newline (buffer);
+
+ record_last_error_function ();
+ output_destroy_prefix (buffer);
+ output_buffer_state (buffer) = os;
+ }
+}
+
+/* Returns a description of FUNCTION using standard terminology. */
+static const char *
+function_category (fn)
+ tree fn;
+{
+ if (DECL_FUNCTION_MEMBER_P (fn))
+ {
+ if (DECL_STATIC_FUNCTION_P (fn))
+ return "static member function";
+ else if (DECL_COPY_CONSTRUCTOR_P (fn))
+ return "copy constructor";
+ else if (DECL_CONSTRUCTOR_P (fn))
+ return "constructor";
+ else if (DECL_DESTRUCTOR_P (fn))
+ return "destructor";
+ else
+ return "member function";
+ }
+ else
+ return "function";
+}
+
+/* Report the full context of a current template instantiation,
+ onto BUFFER. */
+static void
+print_instantiation_full_context (buffer)
+ output_buffer *buffer;
+{
+ tree p = current_instantiation ();
+ int line = lineno;
+ const char *file = input_filename;
+
+ if (p)
+ {
+ if (current_function_decl != TINST_DECL (p)
+ && current_function_decl != NULL_TREE)
+ /* We can get here during the processing of some synthesized
+ method. Then, TINST_DECL (p) will be the function that's causing
+ the synthesis. */
+ ;
+ else
+ {
+ if (current_function_decl == TINST_DECL (p))
+ /* Avoid redundancy with the the "In function" line. */;
+ else
+ output_verbatim (buffer, "%s: In instantiation of `%s':\n", file,
+ decl_as_string (TINST_DECL (p),
+ TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
+
+ line = TINST_LINE (p);
+ file = TINST_FILE (p);
+ p = TREE_CHAIN (p);
+ }
+ }
+
+ print_instantiation_partial_context (buffer, p, file, line);
+}
+
+/* Same as above but less verbose. */
+static void
+print_instantiation_partial_context (buffer, t, file, line)
+ output_buffer *buffer;
+ tree t;
+ const char *file;
+ int line;
+{
+ for (; t; t = TREE_CHAIN (t))
+ {
+ output_verbatim
+ (buffer, "%s:%d: instantiated from `%s'\n", file, line,
+ decl_as_string (TINST_DECL (t), TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
+ line = TINST_LINE (t);
+ file = TINST_FILE (t);
+ }
+ output_verbatim (buffer, "%s:%d: instantiated from here\n", file, line);
+}
+
+/* Called from cp_thing to print the template context for an error. */
+static void
+maybe_print_instantiation_context (buffer)
+ output_buffer *buffer;
+{
+ if (!problematic_instantiation_changed () || current_instantiation () == 0)
+ return;
+
+ record_last_problematic_instantiation ();
+ print_instantiation_full_context (buffer);
+}
+
+/* Report the bare minimum context of a template instantiation. */
+void
+print_instantiation_context ()
+{
+ print_instantiation_partial_context
+ (diagnostic_buffer, current_instantiation (), input_filename, lineno);
+ flush_diagnostic_buffer ();
+}
+
+/* Called from output_format -- during diagnostic message processing --
+ to handle C++ specific format specifier with the following meanings:
+ %A function argument-list.
+ %C tree code.
+ %D declaration.
+ %E expression.
+ %F function declaration.
+ %L language as used in extern "lang".
+ %O binary operator.
+ %P function parameter whose position is indicated by an integer.
+ %Q assignment operator.
+ %T type.
+ %V cv-qualifier. */
+static int
+cp_printer (buffer)
+ output_buffer *buffer;
+{
+ int verbose = 0;
+ const char *result;
+#define next_tree va_arg (output_buffer_format_args (buffer), tree)
+#define next_tcode va_arg (output_buffer_format_args (buffer), enum tree_code)
+#define next_lang va_arg (output_buffer_format_args (buffer), enum languages)
+#define next_int va_arg (output_buffer_format_args (buffer), int)
+
+ if (*output_buffer_text_cursor (buffer) == '+')
+ ++output_buffer_text_cursor (buffer);
+ if (*output_buffer_text_cursor (buffer) == '#')
+ {
+ verbose = 1;
+ ++output_buffer_text_cursor (buffer);
+ }
+
+ switch (*output_buffer_text_cursor (buffer))
+ {
+ case 'A': result = args_to_string (next_tree, verbose); break;
+ case 'C': result = code_to_string (next_tcode, verbose); break;
+ case 'D': result = decl_to_string (next_tree, verbose); break;
+ case 'E': result = expr_to_string (next_tree, verbose); break;
+ case 'F': result = fndecl_to_string (next_tree, verbose); break;
+ case 'L': result = language_to_string (next_lang, verbose); break;
+ case 'O': result = op_to_string (next_tcode, verbose); break;
+ case 'P': result = parm_to_string (next_int, verbose); break;
+ case 'Q': result = assop_to_string (next_tcode, verbose); break;
+ case 'T': result = type_to_string (next_tree, verbose); break;
+ case 'V': result = cv_to_string (next_tree, verbose); break;
+
+ default:
+ return 0;
+ }
+
+ output_add_string (buffer, result);
+ return 1;
+#undef next_tree
+#undef next_tcode
+#undef next_lang
+#undef next_int
+}
+
+static void
+print_integer (buffer, i)
+ output_buffer *buffer;
+ HOST_WIDE_INT i;
+{
+ sprintf (digit_buffer, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) i);
+ output_add_string (buffer, digit_buffer);
+}
+
+static void
+print_non_consecutive_character (buffer, c)
+ output_buffer *buffer;
+ int c;
+{
+ const char *p = output_last_position (buffer);
+
+ if (p != NULL && *p == c)
+ output_add_space (buffer);
+ output_add_character (buffer, c);
+}
+
+/* These are temporary wrapper functions which handle the historic
+ behavior of cp_*_at. */
+
+static tree
+locate_error (msgid, ap)
+ const char *msgid;
+ va_list ap;
{
- OB_INIT ();
+ tree here = 0, t;
+ int plus = 0;
+ const char *f;
- dump_qualifiers (p, before);
+ for (f = msgid; *f; f++)
+ {
+ plus = 0;
+ if (*f == '%')
+ {
+ f++;
+ if (*f == '+')
+ f++, plus = 1;
+ if (*f == '#')
+ f++;
- OB_FINISH ();
+ switch (*f)
+ {
+ /* Just ignore these possibilities. */
+ case '%': break;
+ case 'd': (void) va_arg (ap, int); break;
+ case 's': (void) va_arg (ap, char *); break;
+ case 'L': (void) va_arg (ap, enum languages); break;
+ case 'C':
+ case 'O':
+ case 'Q': (void) va_arg (ap, enum tree_code); break;
+
+ /* These take a tree, which may be where the error is
+ located. */
+ case 'A':
+ case 'D':
+ case 'E':
+ case 'F':
+ case 'P':
+ case 'T':
+ case 'V':
+ t = va_arg (ap, tree);
+ if (!here || plus)
+ here = t;
+ break;
- return (char *)obstack_base (&scratch_obstack);
+ default:
+ errorcount = 0; /* damn ICE suppression */
+ internal_error ("unexpected letter `%c' in locate_error\n", *f);
+ }
+ }
+ }
+
+ if (here == 0)
+ here = va_arg (ap, tree);
+
+ return here;
+}
+
+
+void
+cp_error_at VPARAMS ((const char *msgid, ...))
+{
+ tree here;
+ diagnostic_context dc;
+
+ VA_OPEN (ap, msgid);
+ VA_FIXEDARG (ap, const char *, msgid);
+ here = locate_error (msgid, ap);
+ VA_CLOSE (ap);
+
+ VA_OPEN (ap, msgid);
+ VA_FIXEDARG (ap, const char *, msgid);
+
+ set_diagnostic_context (&dc, msgid, &ap,
+ cp_file_of (here),
+ cp_line_of (here), /* warning = */ 0);
+ report_diagnostic (&dc);
+ VA_CLOSE (ap);
+}
+
+void
+cp_warning_at VPARAMS ((const char *msgid, ...))
+{
+ tree here;
+ diagnostic_context dc;
+
+ VA_OPEN (ap, msgid);
+ VA_FIXEDARG (ap, const char *, msgid);
+ here = locate_error (msgid, ap);
+ VA_CLOSE (ap);
+
+ VA_OPEN (ap, msgid);
+ VA_FIXEDARG (ap, const char *, msgid);
+
+ set_diagnostic_context (&dc, msgid, &ap,
+ cp_file_of (here),
+ cp_line_of (here), /* warning = */ 1);
+ report_diagnostic (&dc);
+ VA_CLOSE (ap);
+}
+
+void
+cp_pedwarn_at VPARAMS ((const char *msgid, ...))
+{
+ tree here;
+ diagnostic_context dc;
+
+ VA_OPEN (ap, msgid);
+ VA_FIXEDARG (ap, const char *, msgid);
+ here = locate_error (msgid, ap);
+ VA_CLOSE (ap);
+
+ VA_OPEN (ap, msgid);
+ VA_FIXEDARG (ap, const char *, msgid);
+
+ set_diagnostic_context (&dc, msgid, &ap,
+ cp_file_of (here),
+ cp_line_of (here),
+ /* warning = */ !flag_pedantic_errors);
+ report_diagnostic (&dc);
+ VA_CLOSE (ap);
}
OpenPOWER on IntegriCloud