OSDN Git Service

* g++.old-deja/g++.benjamin/16077.C: Adjust warnings.
[pf3gnuchains/gcc-fork.git] / gcc / cp / error.c
index 5a8522a..42a7ff7 100644 (file)
@@ -1,69 +1,55 @@
 /* Call-backs for C++ error reporting.
    This code is non-reentrant.
-   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002
    Free Software Foundation, Inc.
-   This file is part of GNU CC.
+   This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
-GNU CC is distributed in the hope that it will be useful,
+GCC is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
+along with GCC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "cp-tree.h"
-#include "obstack.h"
+#include "real.h"
 #include "toplev.h"
+#include "flags.h"
 #include "diagnostic.h"
+#include "langhooks-def.h"
 
 enum pad { none, before, after };
 
-/* This data structure bundles altogether, all the information necessary
-   for pretty-printing a C++ source-level entity represented by a tree.  */
-typedef struct
-{
-  tree decl;
-  int flags;
-  enum pad pad;
-} tree_formatting_info, *tfi_t;
-
-#define tree_being_formatted(TFI) (TFI)->decl
-#define tree_formatting_flags(TFI) (TFI)->flags
-#define put_whitespace(TFI) (TFI)->pad
-
 #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_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, '<')
+   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)
+   print_non_consecutive_character ((BUFFER), '>')
 #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, ", ")
+   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
@@ -71,143 +57,79 @@ typedef struct
 static output_buffer scratch_buffer_rec;
 static output_buffer *scratch_buffer = &scratch_buffer_rec;
 
-# define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t)))
+# 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 tree ident_fndecl 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 ((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_tree_printer PARAMS ((output_buffer *));
-static void print_function_argument_list PARAMS ((output_buffer *, tfi_t));
-static void print_declaration PARAMS ((output_buffer *, tfi_t));
-static void print_expression PARAMS ((output_buffer *, tfi_t));
-static void print_integer PARAMS ((output_buffer *, HOST_WIDE_INT));
-static void print_function_declaration PARAMS ((output_buffer *, tfi_t));
-static void print_function_parameter PARAMS ((output_buffer *, int));
-static void print_type_id PARAMS ((output_buffer *, tfi_t));
-static void print_cv_qualifier_seq PARAMS ((output_buffer *, tfi_t));
-static void print_type_specifier_seq PARAMS ((output_buffer *, tfi_t));
-static void print_simple_type_specifier PARAMS ((output_buffer *, tfi_t));
-static void print_elaborated_type_specifier PARAMS ((output_buffer *, tfi_t));
-static void print_rest_of_abstract_declarator PARAMS ((output_buffer *,
-                                                       tfi_t));
-static void print_parameter_declaration_clause PARAMS ((output_buffer *,
-                                                        tfi_t));
-static void print_exception_specification PARAMS ((output_buffer *, tfi_t));
-static void print_nested_name_specifier PARAMS ((output_buffer *, tfi_t));
-static void print_template_id PARAMS ((output_buffer *, tfi_t));
-static tree typedef_original_name PARAMS ((tree));
-static void print_non_consecutive_character PARAMS ((output_buffer *, int));
-
-#define A args_to_string
-#define C code_to_string
-#define D decl_to_string
-#define E expr_to_string
-#define F fndecl_to_string
-#define L language_to_string
-#define O op_to_string
-#define P parm_to_string
-#define Q assop_to_string
-#define T type_to_string
-#define V cv_to_string
-
-#define o (cp_printer *) 0
-cp_printer * cp_printers[256] =
-{
-/*0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
-  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x00 */
-  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x10 */
-  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x20 */
-  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x30 */
-  o, A, o, C, D, E, F, o, o, o, o, o, L, o, o, O, /* 0x40 */
-  P, Q, o, o, T, o, V, o, o, o, o, o, o, o, o, o, /* 0x50 */
-  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x60 */
-  o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x70 */
-};
-#undef A
-#undef C
-#undef D
-#undef E
-#undef F
-#undef L
-#undef O
-#undef P
-#undef Q
-#undef T
-#undef V
-#undef o
+static const char *args_to_string (tree, int);
+static const char *assop_to_string (enum tree_code, int);
+static const char *code_to_string (enum tree_code, int);
+static const char *cv_to_string (tree, int);
+static const char *decl_to_string (tree, int);
+static const char *expr_to_string (tree, int);
+static const char *fndecl_to_string (tree, int);
+static const char *op_to_string        (enum tree_code, int);
+static const char *parm_to_string (int, int);
+static const char *type_to_string (tree, int);
+
+static void dump_type (tree, int);
+static void dump_typename (tree, int);
+static void dump_simple_decl (tree, tree, int);
+static void dump_decl (tree, int);
+static void dump_template_decl (tree, int);
+static void dump_function_decl (tree, int);
+static void dump_expr (tree, int);
+static void dump_unary_op (const char *, tree, int);
+static void dump_binary_op (const char *, tree, int);
+static void dump_aggr_type (tree, int);
+static enum pad dump_type_prefix (tree, int);
+static void dump_type_suffix (tree, int);
+static void dump_function_name (tree, int);
+static void dump_expr_list (tree, int);
+static void dump_global_iord (tree);
+static enum pad dump_qualifiers (tree, enum pad);
+static void dump_char (int);
+static void dump_parameters (tree, int);
+static void dump_exception_spec (tree, int);
+static const char *class_key_or_enum (tree);
+static void dump_template_argument (tree, int);
+static void dump_template_argument_list (tree, int);
+static void dump_template_parameter (tree, int);
+static void dump_template_bindings (tree, tree);
+static void dump_scope (tree, int);
+static void dump_template_parms (tree, int, int);
+
+static const char *function_category (tree);
+static void maybe_print_instantiation_context (diagnostic_context *);
+static void print_instantiation_full_context (diagnostic_context *);
+static void print_instantiation_partial_context (diagnostic_context *,
+                                                 tree, const char *, int);
+static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *);
+static void cp_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
+static void cp_print_error_function (diagnostic_context *, diagnostic_info *);
+
+static bool cp_printer (output_buffer *, text_info *);
+static void print_non_consecutive_character (output_buffer *, int);
+static void print_integer (output_buffer *, HOST_WIDE_INT);
+static tree locate_error (const char *, va_list);
 
 void
-init_error ()
+init_error (void)
 {
-  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_tree_printer;
-  
+  diagnostic_format_decoder (global_dc) = cp_printer;
+
   init_output_buffer (scratch_buffer, /* prefix */NULL, /* line-width */0);
 }
 
 /* Dump a scope, if deemed necessary.  */
 
 static void
-dump_scope (scope, flags)
-     tree scope;
-     int flags;
+dump_scope (tree scope, int flags)
 {
-  int f = ~TFF_RETURN_TYPE & (TFF_DECL_SPECIFIERS
-                              | (flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF)));
+  int f = ~TFF_RETURN_TYPE & (flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF));
 
   if (scope == NULL_TREE)
     return;
@@ -236,9 +158,7 @@ dump_scope (scope, flags)
    indication of whether we dumped something.  */
 
 static enum pad
-dump_qualifiers (t, p)
-     tree t;
-     enum pad p;
+dump_qualifiers (tree t, enum pad p)
 {
   static const int masks[] =
     {TYPE_QUAL_CONST, TYPE_QUAL_VOLATILE, TYPE_QUAL_RESTRICT};
@@ -273,9 +193,7 @@ static char digit_buffer[128];
 /* Dump the template ARGument under control of FLAGS.  */
 
 static void
-dump_template_argument (arg, flags)
-     tree arg;
-     int flags;
+dump_template_argument (tree arg, int flags)
 {
   if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
     dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
@@ -287,9 +205,7 @@ dump_template_argument (arg, flags)
    of FLAGS.  */
 
 static void
-dump_template_argument_list (args, flags)
-     tree args;
-     int flags;
+dump_template_argument_list (tree args, int flags)
 {
   int n = TREE_VEC_LENGTH (args);
   int need_comma = 0;
@@ -307,9 +223,7 @@ dump_template_argument_list (args, flags)
 /* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS.  */
 
 static void
-dump_template_parameter (parm, flags)
-     tree parm;
-     int flags;
+dump_template_parameter (tree parm, int flags)
 {
   tree p = TREE_VALUE (parm);
   tree a = TREE_PURPOSE (parm);
@@ -348,8 +262,7 @@ dump_template_parameter (parm, flags)
    TREE_VEC.  */
 
 static void
-dump_template_bindings (parms, args)
-     tree parms, args;
+dump_template_bindings (tree parms, tree args)
 {
   int need_comma = 0;
 
@@ -389,13 +302,11 @@ dump_template_bindings (parms, args)
     }
 }
 
-/* Dump into the obstack a human-readable equivalent of TYPE.  FLAGS
-   controls the format.  */
+/* Dump a human-readable equivalent of TYPE.  FLAGS controls the
+   format.  */
 
 static void
-dump_type (t, flags)
-     tree t;
-     int flags;
+dump_type (tree t, int flags)
 {
   if (t == NULL_TREE)
     return;
@@ -449,7 +360,14 @@ dump_type (t, flags)
 
     case VECTOR_TYPE:
       output_add_string (scratch_buffer, "vector ");
-      dump_type (TREE_TYPE (t), flags);
+      {
+       /* The subtype of a VECTOR_TYPE is something like intQI_type_node,
+          which has no name and is not very useful for diagnostics.  So
+          look up the equivalent C type and print its name.  */
+       tree elt = TREE_TYPE (t);
+       elt = c_common_type_for_mode (TYPE_MODE (elt), TREE_UNSIGNED (elt));
+       dump_type (elt, flags);
+      }
       break;
 
     case INTEGER_TYPE:
@@ -477,7 +395,7 @@ dump_type (t, flags)
       break;
 
     case TEMPLATE_TEMPLATE_PARM:
-      /* For parameters inside template signature. */
+      /* For parameters inside template signature.  */
       if (TYPE_IDENTIFIER (t))
        print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
       else
@@ -519,19 +437,27 @@ dump_type (t, flags)
       break;
     }
     case TYPENAME_TYPE:
+      dump_qualifiers (t, after);
       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:
       output_add_string (scratch_buffer, "__typeof (");
       dump_expr (TYPE_FIELDS (t), flags & ~TFF_EXPR_IN_PARENS);
-      print_left_paren (scratch_buffer);
+      print_right_paren (scratch_buffer);
       break;
 
     default:
       sorry_for_unsupported_tree (t);
-      /* Fall through to error. */
+      /* Fall through to error.  */
 
     case ERROR_MARK:
       print_identifier (scratch_buffer, "<type error>");
@@ -543,9 +469,7 @@ dump_type (t, flags)
    a TYPENAME_TYPE.  */
 
 static void
-dump_typename (t, flags)
-     tree t;
-     int flags;
+dump_typename (tree t, int flags)
 {
   tree ctx = TYPE_CONTEXT (t);
 
@@ -560,8 +484,7 @@ dump_typename (t, flags)
 /* Return the name of the supplied aggregate, or enumeral type.  */
 
 static const char *
-class_key_or_enum (t)
-     tree t;
+class_key_or_enum (tree t)
 {
   if (TREE_CODE (t) == ENUMERAL_TYPE)
     return "enum";
@@ -577,9 +500,7 @@ class_key_or_enum (t)
    in the form `class foo'.  */
 
 static void
-dump_aggr_type (t, flags)
-     tree t;
-     int flags;
+dump_aggr_type (tree t, int flags)
 {
   tree name;
   const char *variety = class_key_or_enum (t);
@@ -652,9 +573,7 @@ dump_aggr_type (t, flags)
    want to pad non-*, non-& cores, but not pad * or & types.  */
 
 static enum pad
-dump_type_prefix (t, flags)
-     tree t;
-     int flags;
+dump_type_prefix (tree t, int flags)
 {
   enum pad padding = before;
 
@@ -744,6 +663,7 @@ dump_type_prefix (t, flags)
     case TYPENAME_TYPE:
     case COMPLEX_TYPE:
     case VECTOR_TYPE:
+    case TYPEOF_TYPE:
       dump_type (t, flags);
       padding = before;
       break;
@@ -762,9 +682,7 @@ dump_type_prefix (t, flags)
    which appears after the identifier (or function parms).  */
 
 static void
-dump_type_suffix (t, flags)
-     tree t;
-     int flags;
+dump_type_suffix (tree t, int flags)
 {
   if (TYPE_PTRMEMFUNC_P (t))
     t = TYPE_PTRMEMFUNC_FN_TYPE (t);
@@ -796,8 +714,8 @@ dump_type_suffix (t, flags)
        if (TREE_CODE (t) == METHOD_TYPE)
          dump_qualifiers
            (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before);
-       dump_type_suffix (TREE_TYPE (t), flags);
        dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags);
+       dump_type_suffix (TREE_TYPE (t), flags);
        break;
       }
 
@@ -840,6 +758,7 @@ dump_type_suffix (t, flags)
     case TYPENAME_TYPE:
     case COMPLEX_TYPE:
     case VECTOR_TYPE:
+    case TYPEOF_TYPE:
       break;
 
     default:
@@ -851,33 +770,8 @@ dump_type_suffix (t, flags)
     }
 }
 
-/* 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;
-}
-
-#define GLOBAL_THING "_GLOBAL__"
-
 static void
-dump_global_iord (t)
-     tree t;
+dump_global_iord (tree t)
 {
   const char *p = NULL;
 
@@ -886,16 +780,13 @@ dump_global_iord (t)
   else if (DECL_GLOBAL_DTOR_P (t))
     p = "destructors";
   else
-    my_friendly_abort (352);
+    abort ();
 
   output_printf (scratch_buffer, "(static %s for %s)", p, input_filename);
 }
 
 static void
-dump_simple_decl (t, type, flags)
-     tree t;
-     tree type;
-     int flags;
+dump_simple_decl (tree t, tree type, int flags)
 {
   if (flags & TFF_DECL_SPECIFIERS)
     {
@@ -915,9 +806,7 @@ dump_simple_decl (t, type, flags)
 /* Dump a human readable string for the decl T under control of FLAGS.  */
 
 static void
-dump_decl (t, flags)
-     tree t;
-     int flags;
+dump_decl (tree t, int flags)
 {
   if (t == NULL_TREE)
     return;
@@ -931,7 +820,7 @@ dump_decl (t, flags)
          {
            if ((flags & TFF_DECL_SPECIFIERS)
                && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
-             /* Say `class T' not just `T'. */
+             /* Say `class T' not just `T'.  */
              output_add_string (scratch_buffer, "class ");
 
            dump_type (TREE_TYPE (t), flags);
@@ -949,13 +838,8 @@ dump_decl (t, flags)
       if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
        {
          output_add_string (scratch_buffer, "vtable for ");
-         if (TYPE_P (DECL_CONTEXT (t)))
-           dump_type (DECL_CONTEXT (t), flags);
-         else
-           /* This case can arise with -fno-vtable-thunks.  See
-              expand_upcast_fixups.  It's not clear what to print
-              here.  */
-           print_identifier (scratch_buffer, "<unknown type>");
+         my_friendly_assert (TYPE_P (DECL_CONTEXT (t)), 20010720);
+         dump_type (DECL_CONTEXT (t), flags);
          break;
        }
       /* else fall through */
@@ -998,33 +882,43 @@ dump_decl (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)
-         {
-           output_add_character (scratch_buffer, '~');
-           dump_decl (DECL_NAME (f), flags);
-         }
-       else 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);
-      }
+      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:
+      if (OVL_CHAIN (t))
+       {
+         t = OVL_CURRENT (t);
+         if (DECL_CLASS_SCOPE_P (t))
+           {
+             dump_type (DECL_CONTEXT (t), flags);
+             output_add_string (scratch_buffer, "::");
+           }
+         else if (DECL_CONTEXT (t))
+           {
+             dump_decl (DECL_CONTEXT (t), flags);
+             output_add_string (scratch_buffer, "::");
+           }
+         dump_decl (DECL_NAME (t), flags);
+         break;
+       }
+      
+      /* If there's only one function, just treat it like an ordinary
+        FUNCTION_DECL.  */
       t = OVL_CURRENT (t);
       /* Fall through.  */
 
@@ -1038,7 +932,7 @@ dump_decl (t, flags)
       break;
 
     case TEMPLATE_DECL:
-        dump_template_decl (t, flags);
+      dump_template_decl (t, flags);
       break;
 
     case TEMPLATE_ID_EXPR:
@@ -1087,6 +981,10 @@ dump_decl (t, flags)
       print_tree_identifier (scratch_buffer, DECL_NAME (t));
       break;
 
+    case BASELINK:
+      dump_decl (BASELINK_FUNCTIONS (t), flags);
+      break;
+
     default:
       sorry_for_unsupported_tree (t);
       /* Fallthrough to error.  */
@@ -1101,9 +999,7 @@ dump_decl (t, flags)
    'template <...> leaders plus the 'class X' or 'void fn(...)' part.  */
 
 static void
-dump_template_decl (t, flags)
-     tree t;
-     int flags;
+dump_template_decl (tree t, int flags)
 {
   tree orig_parms = DECL_TEMPLATE_PARMS (t);
   tree parms;
@@ -1119,6 +1015,11 @@ dump_template_decl (t, flags)
           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)
@@ -1129,10 +1030,12 @@ dump_template_decl (t, flags)
           output_add_space (scratch_buffer);
         }
       nreverse(orig_parms);
-      /* If we've shown the template<args> prefix, we'd better show the
-        decl's type too.  */
-      flags |= TFF_DECL_SPECIFIERS;
+
+      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
@@ -1140,7 +1043,7 @@ dump_template_decl (t, flags)
   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)
-    my_friendly_abort (353);
+    abort ();
   else
     switch (NEXT_CODE (t))
     {
@@ -1149,7 +1052,7 @@ dump_template_decl (t, flags)
         dump_function_decl (t, flags | TFF_TEMPLATE_NAME);
         break;
       default:
-        /* This case can occur with some illegal code.  */
+        /* This case can occur with some invalid 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));
@@ -1158,13 +1061,11 @@ dump_template_decl (t, flags)
 
 /* Pretty print a function decl. There are several ways we want to print a
    function declaration. The TFF_ bits in FLAGS tells us how to behave.
-   As cp_error can only apply the '#' flag once to give 0 and 1 for V, there
-   is %D which doesn't print the throw specs, and %F which does. */
+   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, flags)
-     tree t;
-     int flags;
+dump_function_decl (tree t, int flags)
 {
   tree fntype;
   tree parmtypes;
@@ -1227,19 +1128,19 @@ dump_function_decl (t, flags)
 
   dump_function_name (t, flags);
 
-  if (flags & TFF_DECL_SPECIFIERS) 
+  if (1)
     {
       dump_parameters (parmtypes, flags);
 
-      if (show_return)
-       dump_type_suffix (TREE_TYPE (fntype), flags);
-
       if (TREE_CODE (fntype) == METHOD_TYPE)
        dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))),
                         before);
 
       if (flags & TFF_EXCEPTION_SPECIFICATION)
        dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), flags);
+
+      if (show_return)
+       dump_type_suffix (TREE_TYPE (fntype), flags);
     }
 
   /* If T is a template instantiation, dump the parameter binding.  */
@@ -1253,12 +1154,10 @@ dump_function_decl (t, flags)
 
 /* 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. */
+   already been removed.  */
 
 static void
-dump_parameters (parmtypes, flags)
-     tree parmtypes;
-     int flags;
+dump_parameters (tree parmtypes, int flags)
 {
   int first;
 
@@ -1287,12 +1186,10 @@ dump_parameters (parmtypes, flags)
   print_right_paren (scratch_buffer);
 }
 
-/* Print an exception specification. T is the exception specification. */
+/* Print an exception specification. T is the exception specification.  */
 
 static void
-dump_exception_spec (t, flags)
-     tree t;
-     int flags;
+dump_exception_spec (tree t, int flags)
 {
   if (t)
     {
@@ -1314,12 +1211,13 @@ dump_exception_spec (t, flags)
    and destructors properly.  */
 
 static void
-dump_function_name (t, flags)
-     tree t;
-     int flags;
+dump_function_name (tree t, int flags)
 {
   tree name = DECL_NAME (t);
 
+  if (TREE_CODE (t) == TEMPLATE_DECL)
+    t = DECL_TEMPLATE_RESULT (t);
+
   /* Don't let the user see __comp_ctor et al.  */
   if (DECL_CONSTRUCTOR_P (t)
       || DECL_DESTRUCTOR_P (t))
@@ -1362,10 +1260,7 @@ dump_function_name (t, flags)
    decoration.  */
 
 static void
-dump_template_parms (info, primary, flags)
-     tree info;
-     int primary;
-     int flags;
+dump_template_parms (tree info, int primary, int flags)
 {
   tree args = info ? TI_ARGS (info) : NULL_TREE;
 
@@ -1438,8 +1333,7 @@ dump_template_parms (info, primary, flags)
 }
 
 static void
-dump_char (c)
-     int c;
+dump_char (int c)
 {
   switch (c)
     {
@@ -1487,9 +1381,7 @@ dump_char (c)
 /* Print out a list of initializers (subr of dump_expr) */
 
 static void
-dump_expr_list (l, flags)
-     tree l;
-     int flags;
+dump_expr_list (tree l, int flags)
 {
   while (l)
     {
@@ -1500,13 +1392,14 @@ dump_expr_list (l, flags)
     }
 }
 
-/* Print out an expression E under control of FLAGS. */
+/* Print out an expression E under control of FLAGS.  */
 
 static void
-dump_expr (t, flags)
-     tree t;
-     int flags;
+dump_expr (tree t, int flags)
 {
+  if (t == 0)
+    return;
+  
   switch (TREE_CODE (t))
     {
     case VAR_DECL:
@@ -1517,6 +1410,7 @@ dump_expr (t, flags)
     case TEMPLATE_DECL:
     case NAMESPACE_DECL:
     case OVERLOAD:
+    case IDENTIFIER_NODE:
       dump_decl (t, flags & ~TFF_DECL_SPECIFIERS);
       break;
 
@@ -1556,7 +1450,11 @@ dump_expr (t, flags)
        else if (type == char_type_node)
          {
            output_add_character (scratch_buffer, '\'');
-           dump_char (tree_low_cst (t, 0));
+           if (host_integerp (t, TREE_UNSIGNED (type)))
+             dump_char (tree_low_cst (t, TREE_UNSIGNED (type)));
+           else
+             output_printf (scratch_buffer, "\\x%x",
+                            (unsigned int) TREE_INT_CST_LOW (t));
            output_add_character (scratch_buffer, '\'');
          }
        else
@@ -1591,17 +1489,8 @@ dump_expr (t, flags)
       break;
 
     case REAL_CST:
-#ifndef REAL_IS_NOT_DOUBLE
-      sprintf (digit_buffer, "%g", TREE_REAL_CST (t));
-#else
-      {
-       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
+      real_to_decimal (digit_buffer, &TREE_REAL_CST (t),
+                      sizeof (digit_buffer), 0, 1);
       output_add_string (scratch_buffer, digit_buffer);
       break;
 
@@ -1818,7 +1707,7 @@ dump_expr (t, flags)
       break;
 
     case CONVERT_EXPR:
-      if (VOID_TYPE_P (TREE_TYPE (t)))
+      if (TREE_TYPE (t) && VOID_TYPE_P (TREE_TYPE (t)))
        {
          print_left_paren (scratch_buffer);
          dump_type (TREE_TYPE (t), flags);
@@ -1917,16 +1806,9 @@ dump_expr (t, flags)
     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_ptrmemfunc_access_expr (t, pfn_identifier);
 
-         if (integer_all_onesp (idx))
-           {
-             tree pfn = PFN_FROM_PTRMEMFUNC (t);
-             dump_unary_op ("&", pfn, flags | TFF_EXPR_IN_PARENS);
-             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.  */
              output_add_string (scratch_buffer, "((");
@@ -1977,7 +1859,8 @@ dump_expr (t, flags)
              /* A::f */
              dump_expr (t, flags | TFF_EXPR_IN_PARENS);
            else if (BASELINK_P (t))
-             dump_expr (OVL_CURRENT (TREE_VALUE (t)), flags | TFF_EXPR_IN_PARENS);
+             dump_expr (OVL_CURRENT (BASELINK_FUNCTIONS (t)), 
+                        flags | TFF_EXPR_IN_PARENS);
            else
              dump_decl (t, flags);
          }
@@ -2002,10 +1885,6 @@ dump_expr (t, flags)
       dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
       break;
 
-    case IDENTIFIER_NODE:
-      print_tree_identifier (scratch_buffer, t);
-      break;
-
     case SCOPE_REF:
       dump_type (TREE_OPERAND (t, 0), flags);
       print_scope_operator (scratch_buffer);
@@ -2120,12 +1999,10 @@ dump_expr (t, flags)
       output_add_string (scratch_buffer, ") break; ");
       break;
 
-    case TREE_LIST:
-      if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
-       {
-         print_tree_identifier (scratch_buffer, DECL_NAME (TREE_VALUE (t)));
-         break;
-       }
+    case BASELINK:
+      print_tree_identifier (scratch_buffer, DECL_NAME (get_first_fn (t)));
+      break;
+
       /* else fall through */
 
       /*  This list is incomplete, but should suffice for now.
@@ -2141,10 +2018,7 @@ dump_expr (t, flags)
 }
 
 static void
-dump_binary_op (opstring, t, flags)
-     const char *opstring;
-     tree t;
-     int flags;
+dump_binary_op (const char *opstring, tree t, int flags)
 {
   print_left_paren (scratch_buffer);
   dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
@@ -2159,10 +2033,7 @@ dump_binary_op (opstring, t, flags)
 }
 
 static void
-dump_unary_op (opstring, t, flags)
-     const char *opstring;
-     tree t;
-     int flags;
+dump_unary_op (const char *opstring, tree t, int flags)
 {
   if (flags & TFF_EXPR_IN_PARENS)
     print_left_paren (scratch_buffer);
@@ -2176,9 +2047,7 @@ dump_unary_op (opstring, t, flags)
    control.  */
 
 const char *
-type_as_string (typ, flags)
-     tree typ;
-     int flags;
+type_as_string (tree typ, int flags)
 {
   reinit_global_formatting_buffer ();
 
@@ -2188,9 +2057,7 @@ type_as_string (typ, flags)
 }
 
 const char *
-expr_as_string (decl, flags)
-     tree decl;
-     int flags;
+expr_as_string (tree decl, int flags)
 {
   reinit_global_formatting_buffer ();
 
@@ -2200,9 +2067,7 @@ expr_as_string (decl, flags)
 }
 
 const char *
-decl_as_string (decl, flags)
-     tree decl;
-     int flags;
+decl_as_string (tree decl, int flags)
 {
   reinit_global_formatting_buffer ();
 
@@ -2212,9 +2077,7 @@ decl_as_string (decl, flags)
 }
 
 const char *
-context_as_string (context, flags)
-     tree context;
-     int flags;
+context_as_string (tree context, int flags)
 {
   reinit_global_formatting_buffer ();
 
@@ -2223,12 +2086,10 @@ context_as_string (context, flags)
   return output_finalize_message (scratch_buffer);
 }
 
-/* Generate the three forms of printable names for lang_printable_name.  */
+/* Generate the three forms of printable names for cxx_printable_name.  */
 
 const char *
-lang_decl_name (decl, v)
-     tree decl;
-     int v;
+lang_decl_name (tree decl, int v)
 {
   if (v >= 2)
     return decl_as_string (decl, TFF_DECL_SPECIFIERS);
@@ -2250,8 +2111,7 @@ lang_decl_name (decl, v)
 }
 
 const char *
-cp_file_of (t)
-     tree t;
+cp_file_of (tree t)
 {
   if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
     return DECL_SOURCE_FILE (DECL_CONTEXT (t));
@@ -2264,8 +2124,7 @@ cp_file_of (t)
 }
 
 int
-cp_line_of (t)
-     tree t;
+cp_line_of (tree t)
 {
   int line = 0;
   if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
@@ -2287,14 +2146,12 @@ cp_line_of (t)
   return line;
 }
 
-/* Now the interfaces from cp_error et al to dump_type et al. Each takes an
+/* 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;
+decl_to_string (tree decl, int verbose)
 {
   int flags = 0;
 
@@ -2315,9 +2172,7 @@ decl_to_string (decl, verbose)
 }
 
 static const char *
-expr_to_string (decl, verbose)
-     tree decl;
-     int verbose ATTRIBUTE_UNUSED;
+expr_to_string (tree decl, int verbose ATTRIBUTE_UNUSED)
 {
   reinit_global_formatting_buffer ();
 
@@ -2327,9 +2182,7 @@ expr_to_string (decl, verbose)
 }
 
 static const char *
-fndecl_to_string (fndecl, verbose)
-     tree fndecl;
-     int verbose;
+fndecl_to_string (tree fndecl, int verbose)
 {
   int flags;
 
@@ -2345,17 +2198,13 @@ fndecl_to_string (fndecl, verbose)
 
 
 static const char *
-code_to_string (c, v)
-     enum tree_code c;
-     int v ATTRIBUTE_UNUSED;
+code_to_string (enum tree_code c, int v ATTRIBUTE_UNUSED)
 {
   return tree_code_name [c];
 }
 
 const char *
-language_to_string (c, v)
-     enum languages c;
-     int v ATTRIBUTE_UNUSED;
+language_to_string (enum languages c, int v ATTRIBUTE_UNUSED)
 {
   switch (c)
     {
@@ -2369,7 +2218,7 @@ language_to_string (c, v)
       return "Java";
 
     default:
-      my_friendly_abort (355);
+      abort ();
       return 0;
     }
 }
@@ -2377,9 +2226,7 @@ language_to_string (c, v)
 /* Return the proper printed version of a parameter to a C++ function.  */
 
 static const char *
-parm_to_string (p, v)
-     int p;
-     int v ATTRIBUTE_UNUSED;
+parm_to_string (int p, int v ATTRIBUTE_UNUSED)
 {
   if (p < 0)
     return "`this'";
@@ -2389,9 +2236,7 @@ parm_to_string (p, v)
 }
 
 static const char *
-op_to_string (p, v)
-     enum tree_code p;
-     int v ATTRIBUTE_UNUSED;
+op_to_string (enum tree_code p, int v ATTRIBUTE_UNUSED)
 {
   tree id;
 
@@ -2400,9 +2245,7 @@ op_to_string (p, v)
 }
 
 static const char *
-type_to_string (typ, verbose)
-     tree typ;
-     int verbose;
+type_to_string (tree typ, int verbose)
 {
   int flags;
 
@@ -2419,9 +2262,7 @@ type_to_string (typ, verbose)
 }
 
 static const char *
-assop_to_string (p, v)
-     enum tree_code p;
-     int v ATTRIBUTE_UNUSED;
+assop_to_string (enum tree_code p, int v ATTRIBUTE_UNUSED)
 {
   tree id;
 
@@ -2430,9 +2271,7 @@ assop_to_string (p, v)
 }
 
 static const char *
-args_to_string (p, verbose)
-     tree p;
-     int verbose;
+args_to_string (tree p, int verbose)
 {
   int flags = 0;
   if (verbose)
@@ -2458,87 +2297,73 @@ args_to_string (p, verbose)
 }
 
 static const char *
-cv_to_string (p, v)
-     tree p;
-     int v ATTRIBUTE_UNUSED;
+cv_to_string (tree p, int v)
 {
   reinit_global_formatting_buffer ();
 
-  dump_qualifiers (p, before);
+  dump_qualifiers (p, v ? before : none);
 
   return output_finalize_message (scratch_buffer);
 }
 
-static void
-lang_print_error_function (file)
-     const char *file;
+/* Langhook for print_error_function.  */
+void
+cxx_print_error_function (diagnostic_context *context, const char *file)
 {
-  output_state os;
-
-  default_print_error_function (file);
-  os = output_buffer_state (diagnostic_buffer);
-  output_set_prefix (diagnostic_buffer, file);
-  maybe_print_instantiation_context (diagnostic_buffer);
-  output_buffer_state (diagnostic_buffer) = os;
+  lhd_print_error_function (context, file);
+  output_set_prefix (&context->buffer, file);
+  maybe_print_instantiation_context (context);
 }
 
 static void
-cp_diagnostic_starter (buffer, dc)
-     output_buffer *buffer;
-     diagnostic_context *dc;
+cp_diagnostic_starter (diagnostic_context *context,
+                       diagnostic_info *diagnostic)
 {
-  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)));
+  diagnostic_report_current_module (context);
+  cp_print_error_function (context, diagnostic);
+  maybe_print_instantiation_context (context);
+  output_set_prefix (&context->buffer, diagnostic_build_prefix (diagnostic));
 }
 
 static void
-cp_diagnostic_finalizer (buffer, dc)
-     output_buffer *buffer;
-     diagnostic_context *dc __attribute__ ((__unused__));
+cp_diagnostic_finalizer (diagnostic_context *context,
+                         diagnostic_info *diagnostic ATTRIBUTE_UNUSED)
 {
-  output_destroy_prefix (buffer);
+  output_destroy_prefix (&context->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;
+cp_print_error_function (diagnostic_context *context,
+                         diagnostic_info *diagnostic)
 {
-  if (error_function_changed ())
+  if (diagnostic_last_function_changed (context))
     {
-      char *prefix = diagnostic_file_location (dc)
-        ? file_name_as_prefix (diagnostic_file_location (dc))
+      const char *old_prefix = output_prefix (&context->buffer);
+      char *new_prefix = diagnostic->location.file
+        ? file_name_as_prefix (diagnostic->location.file)
         : NULL;
-      output_state os;
 
-      os = output_buffer_state (buffer);
-      output_set_prefix (buffer, prefix);
+      output_set_prefix (&context->buffer, new_prefix);
 
       if (current_function_decl == NULL)
-        output_add_string (buffer, "At global scope:");
+        output_add_string (&context->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;
+        output_printf (&context->buffer, "In %s `%s':",
+                       function_category (current_function_decl),
+                       cxx_printable_name (current_function_decl, 2));
+      output_add_newline (&context->buffer);
+
+      diagnostic_set_last_function (context);
+      output_destroy_prefix (&context->buffer);
+      context->buffer.state.prefix = old_prefix;
     }
 }
 
 /* Returns a description of FUNCTION using standard terminology.  */
 static const char *
-function_category (fn)
-     tree fn;
+function_category (tree fn)
 {
   if (DECL_FUNCTION_MEMBER_P (fn))
     {
@@ -2560,8 +2385,7 @@ function_category (fn)
 /* Report the full context of a current template instantiation,
    onto BUFFER.  */
 static void
-print_instantiation_full_context (buffer)
-     output_buffer *buffer;
+print_instantiation_full_context (diagnostic_context *context)
 {
   tree p = current_instantiation ();
   int line = lineno;
@@ -2580,7 +2404,8 @@ print_instantiation_full_context (buffer)
          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,
+           output_verbatim (&context->buffer,
+                             "%s: In instantiation of `%s':\n", file,
                              decl_as_string (TINST_DECL (p),
                                              TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
 
@@ -2590,789 +2415,236 @@ print_instantiation_full_context (buffer)
        }
     }
 
-  print_instantiation_partial_context (buffer, p, file, line);
+  print_instantiation_partial_context (context, 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;
+print_instantiation_partial_context (diagnostic_context *context,
+                                     tree t, const char *file, int line)
 {
   for (; t; t = TREE_CHAIN (t))
     {
       output_verbatim
-        (buffer, "%s:%d:   instantiated from `%s'\n", file, line,
+        (&context->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);
+  output_verbatim (&context->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;
+maybe_print_instantiation_context (diagnostic_context *context)
 {
   if (!problematic_instantiation_changed () || current_instantiation () == 0)
     return;
 
   record_last_problematic_instantiation ();
-  print_instantiation_full_context (buffer);
+  print_instantiation_full_context (context);
 }
 
 /* Report the bare minimum context of a template instantiation.  */
 void
-print_instantiation_context ()
+print_instantiation_context (void)
 {
   print_instantiation_partial_context
-    (diagnostic_buffer, current_instantiation (), input_filename, lineno);
-  flush_diagnostic_buffer ();
+    (global_dc, current_instantiation (), input_filename, lineno);
+  diagnostic_flush_buffer (global_dc);
 }
 \f
 /* 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_tree_printer (buffer)
-     output_buffer *buffer;
-{
-  int be_verbose = 0;
-  tree_formatting_info tfi;
-
-  memset (&tfi, 0, sizeof (tree_formatting_info));
-
-  if (*output_buffer_text_cursor (buffer) == '+')
-    ++output_buffer_text_cursor (buffer);
-  if (*output_buffer_text_cursor (buffer) == '#')
+static bool
+cp_printer (output_buffer *buffer, text_info *text)
+{
+  int verbose = 0;
+  const char *result;
+#define next_tree    va_arg (*text->args_ptr, tree)
+#define next_tcode   va_arg (*text->args_ptr, enum tree_code)
+#define next_lang    va_arg (*text->args_ptr, enum languages)
+#define next_int     va_arg (*text->args_ptr, int)
+
+  if (*text->format_spec == '+')
+    ++text->format_spec;
+  if (*text->format_spec == '#')
     {
-      be_verbose = 1;
-      ++output_buffer_text_cursor (buffer);
+      verbose = 1;
+      ++text->format_spec;
     }
 
-  switch (*output_buffer_text_cursor (buffer))
+  switch (*text->format_spec)
     {
-    case 'A':
-      tree_being_formatted (&tfi) =
-        va_arg (output_buffer_format_args (buffer), tree);
-      if (be_verbose)
-        tree_formatting_flags (&tfi) = TFF_SCOPE
-          | TFF_FUNCTION_DEFAULT_ARGUMENTS;
-      print_function_argument_list (buffer, &tfi);
-      break;
-
-    case 'D':
-      tree_being_formatted (&tfi) =
-        va_arg (output_buffer_format_args (buffer), tree);
-      if (be_verbose)
-        tree_formatting_flags (&tfi) = TFF_SCOPE | TFF_DECL_SPECIFIERS
-          | TFF_CLASS_KEY_OR_ENUM | TFF_RETURN_TYPE
-          | TFF_FUNCTION_DEFAULT_ARGUMENTS | TFF_TEMPLATE_DEFAULT_ARGUMENTS
-          | TFF_EXCEPTION_SPECIFICATION | TFF_CHASE_NAMESPACE_ALIAS;
-      print_declaration (buffer, &tfi);
-      break;
-
-    case 'E':
-      tree_being_formatted (&tfi) =
-        va_arg (output_buffer_format_args (buffer), tree);
-      if (be_verbose)
-        tree_formatting_flags (&tfi) = TFF_SCOPE;
-      print_expression (buffer, &tfi);
-      break;
-
-    case 'F':
-      tree_being_formatted (&tfi) =
-        va_arg (output_buffer_format_args (buffer), tree);
-      if (be_verbose)
-        tree_formatting_flags (&tfi) = TFF_SCOPE | TFF_DECL_SPECIFIERS
-          | TFF_RETURN_TYPE | TFF_FUNCTION_DEFAULT_ARGUMENTS
-          | TFF_EXCEPTION_SPECIFICATION;
-      print_function_declaration (buffer, &tfi);
-      break;
-
-    case 'P':
-      print_function_parameter
-        (buffer, va_arg (output_buffer_format_args (buffer), int));
-      break;
-
-    case 'T':
-      tree_being_formatted (&tfi) =
-        va_arg (output_buffer_format_args (buffer), tree);
-      if (be_verbose)
-        tree_formatting_flags (&tfi) = TFF_SCOPE | TFF_CLASS_KEY_OR_ENUM
-          | TFF_RETURN_TYPE | TFF_EXCEPTION_SPECIFICATION;
-      print_type_id (buffer, &tfi);
-      break;
-
-    case 'V':
-      tree_being_formatted (&tfi) =
-        va_arg (output_buffer_format_args (buffer), tree);
-      print_cv_qualifier_seq (buffer, &tfi);
-      break;
-
+    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;
+      return false;
     }
 
-  return 1;
+  output_add_string (buffer, result);
+  return true;
+#undef next_tree
+#undef next_tcode
+#undef next_lang
+#undef next_int
 }
 
-/* Print a function argument-list represented by tree_being_formatted (TFI)
-   onto BUFFER.  */
 static void
-print_function_argument_list (buffer, tfi)
-     output_buffer *buffer __attribute__ ((__unused__));
-     tfi_t tfi __attribute__  ((__unused__));
-{
-}
-
-/* Print a declaration represented by tree_being_formatted (TFI)
-   onto buffer.  */
-static void
-print_declaration (buffer, tfi)
-     output_buffer *buffer __attribute__ ((__unused__));
-     tfi_t tfi __attribute__ ((__unused__));
-{
-}
-
-/* Print an expression represented by tree_being_formatted (TFI)
-   onto BUFFER.  */
-static void
-print_expression (buffer, tfi)
-     output_buffer *buffer __attribute__ ((__unused__));
-     tfi_t tfi __attribute__ ((__unused__));
-{
-}
-
-static void
-print_integer (buffer, i)
-     output_buffer *buffer;
-     HOST_WIDE_INT i;
+print_integer (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);
 }
 
-/* Print a function declaration represented by tree_being_formatted (TFI)
-   onto BUFFER.  */
-static void
-print_function_declaration (buffer, tfi)
-     output_buffer *buffer __attribute__ ((__unused__));
-     tfi_t tfi __attribute__ ((__unused__));
-{
-}
-
-/* Print the N'th function parameter onto BUFFER.  A negative value of N
-   means the implicit "this" parameter of a member function.  */
 static void
-print_function_parameter (buffer, n)
-     output_buffer *buffer;
-     int n;
+print_non_consecutive_character (output_buffer *buffer, int c)
 {
-  if (n < 0)
-    print_identifier (buffer, "this");
-  else
-    output_decimal (buffer, n + 1);
-}
-\f
-/* Print a type represented by tree_being_formatted (TFI) onto BUFFER.  */
-static void
-print_type_id (buffer, tfi)
-     output_buffer *buffer;
-     tfi_t tfi;
-{
-  tree t = tree_being_formatted (tfi);
-  int flags = tree_formatting_flags (tfi);
-  if (t == NULL_TREE)
-    return;
-
-  if (flags & TFF_CHASE_TYPEDEF)
-    tree_being_formatted (tfi) =
-      typedef_original_name (tree_being_formatted (tfi));
-
-  /* A type-id is of the form:
-     type-id:
-        type-specifier-seq abstract-declarator(opt)  */
-  print_type_specifier_seq (buffer, tfi);
-
-  if (TYPE_PTRMEMFUNC_P (t))
-    goto ptr_mem_fun;
-
-  /* For types with abstract-declarator, print_type_specifier_seq prints
-     the start of the abstract-declarator.  Fiinish the job.  */
-  switch (TREE_CODE (t))
-    {
-    case ARRAY_TYPE:
-    case POINTER_TYPE:
-    case REFERENCE_TYPE:
-    case OFFSET_TYPE:
-    case METHOD_TYPE:
-    case FUNCTION_TYPE:
-    ptr_mem_fun:
-      print_rest_of_abstract_declarator (buffer, tfi);
-
-    default:
-      break;
-    }
+  const char *p = output_last_position (buffer);
 
-  tree_being_formatted (tfi) = t;
+  if (p != NULL && *p == c)
+    output_add_space (buffer);
+  output_add_character (buffer, c);
 }
 
-/* Print the type-specifier-seq part of a type-id.  If appropriate, print
- also the prefix of the abstract-declarator.  */
-static void
-print_type_specifier_seq (buffer, tfi)
-     output_buffer *buffer;
-     tfi_t tfi;
-{
-  int flags = tree_formatting_flags (tfi);
-  tree t = tree_being_formatted (tfi);
-  enum tree_code code = TREE_CODE (t);
-
-  /* A type-speficier-seq is:
-         type-specifier type-specifier-seq(opt)
-     where
-         type-specifier:
-             simple-type-specifier
-             class-specifier
-             enum-specifier
-             elaborated-type-specifier
-             cv-qualifier
-
-     We do not, however, pretty-print class-specifier nor enum-specifier.  */
-
-  switch (code)
-    {
-    case UNKNOWN_TYPE:
-    case IDENTIFIER_NODE:
-    case VOID_TYPE:
-    case INTEGER_TYPE:
-    case REAL_TYPE:
-    case COMPLEX_TYPE:
-    case ENUMERAL_TYPE:
-    case BOOLEAN_TYPE:
-    case UNION_TYPE:
-    case TYPE_DECL:
-    case TEMPLATE_DECL:
-    case TEMPLATE_TYPE_PARM:
-    case TYPEOF_TYPE:
-    case TEMPLATE_TEMPLATE_PARM:
-    case TYPENAME_TYPE:
-    class_type:
-      print_cv_qualifier_seq (buffer, tfi);
-      if ((flags & TFF_DECL_SPECIFIERS)
-          && (code ==  TYPENAME_TYPE || IS_AGGR_TYPE (t)))
-        print_elaborated_type_specifier (buffer, tfi);
-      else
-        print_simple_type_specifier (buffer, tfi);
-      break;
-
-      /* Because the abstract-declarator can modify the type-specifier-seq
-         in a highly non linear manner, we pretty-print its prefix here.
-         The suffix part is handled by print_rest_of_abstract_declarator.  */
-
-      /* A RECORD_TYPE is also used to represent a pointer to member
-         function.  */
-    case RECORD_TYPE:
-      if (TYPE_PTRMEMFUNC_P (t))
-        {
-          /* Print the return type.  */
-          tree_being_formatted (tfi) =
-            TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (t));
-          print_type_id (buffer, tfi);
-          print_whitespace (buffer, tfi);
-
-          /* Then the beginning of the abstract-declarator part.  */
-          tree_being_formatted (tfi) =
-            TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (t));
-          print_left_paren (buffer);
-          print_nested_name_specifier (buffer, tfi);
-        }
-      else
-        goto class_type;
-      break;
-
-    case POINTER_TYPE:
-      if (TYPE_PTRMEM_P (t))
-        goto ptr_data_member;
-      else
-        goto non_ptr_data_member;
-      break;
-
-    case ARRAY_TYPE:
-    case REFERENCE_TYPE:
-    case FUNCTION_TYPE:
-    case METHOD_TYPE:
-    non_ptr_data_member:
-      tree_being_formatted (tfi) = TREE_TYPE (t);
-      print_type_specifier_seq (buffer, tfi);
-      if (code == POINTER_TYPE || code == REFERENCE_TYPE)
-        {
-          if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
-            print_left_paren (buffer);
-        }
-      else if (code == FUNCTION_TYPE || code == METHOD_TYPE)
-        {
-          print_whitespace (buffer, tfi);
-          print_left_paren (buffer);
-          if (code == METHOD_TYPE)
-            {
-              tree_being_formatted (tfi) = TYPE_METHOD_BASETYPE (t);
-              print_nested_name_specifier (buffer, tfi);
-              tree_being_formatted (tfi) = t;
-            }
-        }
-      tree_being_formatted (tfi) = t;
-      break;
-
-    ptr_data_member:
-    case OFFSET_TYPE:
-      /* Firstly, the type of the member.  */
-      tree_being_formatted (tfi) = TREE_TYPE (t);
-      print_type_id (buffer, tfi);
-      print_whitespace (buffer, tfi);
-
-      /* Then, the containing class.  */
-      tree_being_formatted (tfi) = TYPE_OFFSET_BASETYPE (t);
-      print_nested_name_specifier (buffer, tfi);
-      tree_being_formatted (tfi) = t;
-      break;
+/* These are temporary wrapper functions which handle the historic
+   behavior of cp_*_at.  */
 
-    default:
-      sorry_for_unsupported_tree (t);
-      /* fall throught  */
-
-    case ERROR_MARK:
-      print_identifier (buffer, "{type-specifier-seq error}");
-      break;
-    }
-
-  tree_being_formatted (tfi) = t;
-}
-
-/* Print the simpe-type-specifier component of a type-specifier.  */
-static void
-print_simple_type_specifier (buffer, tfi)
-     output_buffer *buffer;
-     tfi_t tfi;
+static tree
+locate_error (const char *msgid, va_list ap)
 {
-  int flags = tree_formatting_flags (tfi);
-  tree t = tree_being_formatted (tfi);
-  enum tree_code code = TREE_CODE (t);
+  tree here = 0, t;
+  int plus = 0;
+  const char *f;
 
-  switch (code)
+  for (f = msgid; *f; f++)
     {
-    case UNKNOWN_TYPE:
-      print_identifier (buffer, "{unknown type}");
-      break;
-
-    case IDENTIFIER_NODE:
-      print_tree_identifier (buffer, t);
-      break;
-
-    case COMPLEX_TYPE:
-      print_identifier (buffer, "__complex__ ");
-      tree_being_formatted (tfi) = TREE_TYPE (t);
-      print_type_id (buffer, tfi);
-      break;
-
-    case TYPENAME_TYPE:
-      tree_being_formatted (tfi) = TYPE_CONTEXT (t);
-      print_nested_name_specifier (buffer, tfi);
-      tree_being_formatted (tfi) = TYPENAME_TYPE_FULLNAME (t);
-      tree_formatting_flags (tfi) |= ~TFF_CHASE_TYPEDEF;
-      print_type_id (buffer, tfi);
-      break;
-
-    case TYPEOF_TYPE:
-      print_identifier (buffer, "__typeof__");
-      tree_being_formatted (tfi) = TYPE_FIELDS (t);
-      print_left_paren (buffer);
-      print_expression (buffer, tfi);
-      print_right_paren (buffer);
-      break;
-
-    case INTEGER_TYPE:
-      if (TREE_UNSIGNED (t))
-        {
-          if (TYPE_MAIN_VARIANT (t) == integer_type_node)
-            /* We don't want pedantry like `unsigned int'.  */;
-          else if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)))
-            {
-              print_identifier (buffer, "unsigned");
-              print_whitespace (buffer, tfi);
-            }
-        }
-      else if (TYPE_MAIN_VARIANT (t) == char_type_node)
-        {
-          print_identifier (buffer, "signed");
-          print_whitespace (buffer, tfi);
-        }
-    case REAL_TYPE:
-    case BOOLEAN_TYPE:
-    case VOID_TYPE:
-      {
-        tree s = (flags & TFF_CHASE_TYPEDEF) ? TYPE_MAIN_VARIANT (t) : t;
-
-        if (TYPE_NAME (s) && TYPE_IDENTIFIER (s))
-          print_tree_identifier (buffer, TYPE_IDENTIFIER (s));
-        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.  */
-          print_identifier (buffer, "{anonymous}");
-      }
-      break;
-
-    case TEMPLATE_TEMPLATE_PARM:
-      if (TYPE_IDENTIFIER (t))
-        print_tree_identifier (buffer, TYPE_IDENTIFIER (t));
-      else
-        print_identifier (buffer, "{anonymous template template parameter}");
-      break;
-
-    case TYPE_DECL:
-      if (flags & TFF_CHASE_TYPEDEF)
-        print_type_id (buffer, tfi);
-      else
-        print_tree_identifier (buffer, DECL_NAME (t));
-      break;
-
-    case BOUND_TEMPLATE_TEMPLATE_PARM:
-    case TEMPLATE_DECL:
-      print_template_id (buffer, tfi);
-      break;
+      plus = 0;
+      if (*f == '%')
+       {
+         f++;
+         if (*f == '+')
+           f++, plus = 1;
+         if (*f == '#')
+           f++;
 
-    case TEMPLATE_TYPE_PARM:
-      if (TYPE_IDENTIFIER (t))
-        print_tree_identifier (buffer, TYPE_IDENTIFIER (t));
-      else
-        print_identifier (buffer, "{anonymous template type parameter}");
-      break;
+         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;
 
-    default:
-      break;
+           default:
+             errorcount = 0;  /* damn ICE suppression */
+             internal_error ("unexpected letter `%c' in locate_error\n", *f);
+           }
+       }
     }
 
-  tree_being_formatted (tfi) = t;
-  tree_formatting_flags (tfi) = flags;
-}
-
-/* Print the elaborated-type-specifier form of a type-specifier.  */
-static void
-print_elaborated_type_specifier (buffer, tfi)
-     output_buffer *buffer;
-     tfi_t tfi;
-{
-  int flags = tree_formatting_flags (tfi);
-  tree t = tree_being_formatted (tfi);
+  if (here == 0)
+    here = va_arg (ap, tree);
 
-  switch (TREE_CODE (t))
-    {
-    case TYPENAME_TYPE:
-      print_identifier (buffer, "typename");
-      print_whitespace (buffer, tfi);
-      tree_formatting_flags (tfi) |= ~TFF_DECL_SPECIFIERS;
-      print_simple_type_specifier (buffer, tfi);
-      break;
-
-    case UNION_TYPE:
-    case RECORD_TYPE:
-      {
-        tree name = NULL_TREE;
-
-        if (flags & TFF_CHASE_TYPEDEF)
-          tree_being_formatted (tfi) = typedef_original_name (t);
-
-        print_identifier
-          (buffer, class_key_or_enum (tree_being_formatted (tfi)));
-        print_whitespace (buffer, tfi);
-
-        name = TYPE_NAME (tree_being_formatted (tfi));
-        if (name)
-          {
-            if (flags & TFF_SCOPE)
-              {
-                tree_being_formatted (tfi) = CP_DECL_CONTEXT (name);
-                print_nested_name_specifier (buffer, tfi);
-              }
-            print_tree_identifier (buffer, DECL_NAME (name));
-          }
-        else
-          print_identifier (buffer, "{anonymous}");
-      }
-      break;
-
-    default:
-      sorry_for_unsupported_tree (t);
-      break;
-    }
-
-  tree_being_formatted (tfi) = t;
-  tree_formatting_flags (tfi) = flags;
+  return here;
 }
 
-/* Finish the job of printing the abstract-declarator part of a
-   type-id.  */
-static void
-print_rest_of_abstract_declarator (buffer, tfi)
-     output_buffer *buffer;
-     tfi_t tfi;
-{
-  tree t = tree_being_formatted (tfi);
-  enum tree_code code = TREE_CODE (t);
-
-  /* An abstract-declarator has the form:
-
-     abstract-declarator:
-          ptr-operator abstract-declarator(opt)
-          direct-abstract-declarator
-
-     direct-abstract-declarator:
-          direct-abstract-declarator(opt)
-              ( parameter-declaration-clause ) cv-qualifier-seq(opt)
-                    exception-specification(opt)
-          direct-abstract-declarator(opt) [ constant-expression(opt) ]
-          ( direct-abstract-declarator )   */
-
-  switch (code)
-    {
-    case ARRAY_TYPE:
-      print_left_bracket (buffer);
-      if (TYPE_DOMAIN (t))
-       {
-          tree s = TYPE_DOMAIN (t);
-
-         if (host_integerp (TYPE_MAX_VALUE (s), 0))
-           output_decimal (buffer, tree_low_cst (TYPE_MAX_VALUE (s), 0) + 1);
-         else if (TREE_CODE (TYPE_MAX_VALUE (s)) == MINUS_EXPR)
-            {
-              tree_being_formatted (tfi) =
-                TREE_OPERAND (TYPE_MAX_VALUE (s), 0);
-              print_expression (buffer, tfi);
-              tree_being_formatted (tfi) = t;
-            }
-         else
-            {
-              tree_being_formatted (tfi) = fold
-                (cp_build_binary_op (PLUS_EXPR, TYPE_MAX_VALUE (s),
-                                     integer_one_node));
-              print_expression (buffer, tfi);
-              tree_being_formatted (tfi) = t;
-            }
-       }
-      print_right_bracket (buffer);
-      put_whitespace (tfi) = none;
-      tree_being_formatted (tfi) = TREE_TYPE (t);
-      print_rest_of_abstract_declarator (buffer, tfi);
-      tree_being_formatted (tfi) = t;
-      break;
-
-    case POINTER_TYPE:
-    case REFERENCE_TYPE:
-    case OFFSET_TYPE:
-      if (code == POINTER_TYPE || code == REFERENCE_TYPE)
-        {
-          output_add_character (buffer, "&*"[code == POINTER_TYPE]);
-          if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
-            print_right_paren (buffer);
-        }
-      put_whitespace (tfi) = before;
-      print_cv_qualifier_seq (buffer, tfi);
-      tree_being_formatted (tfi) = TREE_TYPE (t);
-      print_rest_of_abstract_declarator (buffer, tfi);
-      tree_being_formatted (tfi) = t;
-      break;
-
-    case FUNCTION_TYPE:
-    case METHOD_TYPE:
-      print_right_paren (buffer);
-      print_whitespace (buffer, tfi);
-
-      /* Skip the `this' implicit parameter if present.  */
-      tree_being_formatted (tfi) = TYPE_ARG_TYPES (t);
-      if (code == METHOD_TYPE)
-        tree_being_formatted (tfi) = TREE_CHAIN (tree_being_formatted (tfi));
-
-      /* Print the parameter-list.  */
-      print_left_paren (buffer);
-      print_parameter_declaration_clause (buffer, tfi);
-      print_right_paren (buffer);
-
-      print_whitespace (buffer, tfi);
-
-      if (code == METHOD_TYPE)
-        {
-          tree_being_formatted (tfi) =
-            TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t)));
-          print_cv_qualifier_seq (buffer, tfi);
-        }
-
-      /* Finish the abstract-declarator.  */
-      tree_being_formatted (tfi) = TREE_TYPE (t);
-      print_rest_of_abstract_declarator (buffer, tfi);
-
-      /* Print the exception-specification for documentaion purpose.  */
-      tree_being_formatted (tfi) = TYPE_RAISES_EXCEPTIONS (t);
-      print_exception_specification (buffer, tfi);
-      tree_being_formatted (tfi) = t;
-      break;
-
-      /* These types don't have abstract-declarator.  */
-    case UNKNOWN_TYPE:
-    case IDENTIFIER_NODE:
-    case VOID_TYPE:
-    case INTEGER_TYPE:
-    case REAL_TYPE:
-    case COMPLEX_TYPE:
-    case ENUMERAL_TYPE:
-    case BOOLEAN_TYPE:
-    case UNION_TYPE:
-    case TYPE_DECL:
-    case TEMPLATE_DECL:
-    case TEMPLATE_TYPE_PARM:
-    case TYPEOF_TYPE:
-    case TEMPLATE_TEMPLATE_PARM:
-    case TYPENAME_TYPE:
-      break;
 
-    default:
-      sorry_for_unsupported_tree (t);
-      /* fall throught.  */
-    case ERROR_MARK:
-      break;
-    }
-}
-
-/* Print the cv-quafilers of tree_being_formatted (TFI) onto BUFFER.  */
-static void
-print_cv_qualifier_seq (buffer, tfi)
-     output_buffer *buffer;
-     tree_formatting_info *tfi;
+void
+cp_error_at VPARAMS ((const char *msgid, ...))
 {
-  int cv = TYPE_QUALS (tree_being_formatted (tfi));
-  int pad_after = after == put_whitespace (tfi);
-  static const int mask[]
-    = {TYPE_QUAL_CONST, TYPE_QUAL_VOLATILE, TYPE_QUAL_RESTRICT};
-  static const char *const qualifier[]
-    = { "const", "volatile", "__restrict__" };
-
-  if (cv != 0)
-    {
-      int i;
-      for (i = 0; i != 3; ++i)
-        if (mask[i] & cv)
-          {
-            if (put_whitespace (tfi) == before)
-              output_add_space (buffer);
-            print_identifier (buffer, qualifier[i]);
-            put_whitespace (tfi) = before;
-          }
+  tree here;
+  diagnostic_info diagnostic;
 
-      if (pad_after)
-        {
-          output_add_space (buffer);
-          put_whitespace (tfi) = none;
-        }
-    }
-}
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
+  here = locate_error (msgid, ap);
+  VA_CLOSE (ap);
 
-static void
-print_parameter_declaration_clause (buffer, tfi)
-     output_buffer *buffer __attribute__ ((__unused__));
-     tfi_t tfi __attribute__ ((__unused__));
-{
-}
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
 
-static void
-print_exception_specification (buffer, tfi)
-     output_buffer *buffer __attribute__ ((__unused__));
-     tfi_t tfi __attribute__ ((__unused__));
-{
+  diagnostic_set_info (&diagnostic, msgid, &ap,
+                       cp_file_of (here), cp_line_of (here), DK_ERROR);
+  report_diagnostic (&diagnostic);
+  VA_CLOSE (ap);
 }
 
-static void
-print_nested_name_specifier (buffer, tfi)
-     output_buffer *buffer;
-     tfi_t tfi;
+void
+cp_warning_at VPARAMS ((const char *msgid, ...))
 {
-  int flags = tree_formatting_flags (tfi);
-  tree t = tree_being_formatted (tfi);
-  /* A nested-name-specifier is:
-        class-or-namespace-name :: nested-name-specifier(opt)
-        class-or-namespace-name :: template nested-name-specifier
-
-     The latter form being the correct syntax for a name  designating
-     a template member, where the preceding class-or-namespace-name part
-     is name-dependent.  For the time being, we do not do such a
-     sophisticated pretty-printing.
-
-     class-or-namespace-name:
-        class-name
-        namespace-name  */
-
-  if (t == NULL_TREE || t == global_namespace)
-    return;
-
-  if (CLASS_TYPE_P (t) && !(flags & TFF_CLASS_SCOPE))
-    return;
+  tree here;
+  diagnostic_info diagnostic;
 
-  if (TREE_CODE (t) == NAMESPACE_DECL && !(flags & TFF_NAMESPACE_SCOPE))
-    return;
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
+  here = locate_error (msgid, ap);
+  VA_CLOSE (ap);
 
-  tree_being_formatted (tfi) = DECL_CONTEXT (t);
-  print_nested_name_specifier (buffer, tfi);
-  print_scope_operator (buffer);
-  if (TREE_CODE (t) == NAMESPACE_DECL)
-    print_tree_identifier (buffer, DECL_NAME (t));
-  else if (CLASS_TYPE_P (t))
-    {
-      if (!DECL_USE_TEMPLATE (t))
-        print_tree_identifier (buffer, TYPE_IDENTIFIER (t));
-      else
-        {
-          tree_being_formatted (tfi) = t;
-          print_template_id (buffer, tfi);
-        }
-    }
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
 
-  tree_being_formatted (tfi) = t;
+  diagnostic_set_info (&diagnostic, msgid, &ap,
+                       cp_file_of (here), cp_line_of (here), DK_WARNING);
+  report_diagnostic (&diagnostic);
+  VA_CLOSE (ap);
 }
 
-static void
-print_template_id (buffer, tfi)
-     output_buffer *buffer;
-     tfi_t tfi __attribute__ ((__unused__));
+void
+cp_pedwarn_at VPARAMS ((const char *msgid, ...))
 {
-  print_template_argument_list_start (buffer);
-  /* ... */
-  print_template_argument_list_end (buffer);
-}
+  tree here;
+  diagnostic_info diagnostic;
 
-static tree
-typedef_original_name (t)
-     tree t;
-{
-  return DECL_ORIGINAL_TYPE (t) ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t);
-}
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
+  here = locate_error (msgid, ap);
+  VA_CLOSE (ap);
 
-static void
-print_non_consecutive_character (buffer, c)
-     output_buffer *buffer;
-     int c;
-{
-  const char *p = output_last_position (buffer);
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, const char *, msgid);
 
-  if (p != NULL && *p == c)
-    output_add_space (buffer);
-  output_add_character (buffer, c);
+  diagnostic_set_info (&diagnostic, msgid, &ap,
+                       cp_file_of (here), cp_line_of (here),
+                       pedantic_error_kind());
+  report_diagnostic (&diagnostic);
+  VA_CLOSE (ap);
 }