+++ /dev/null
-/* Provide a call-back mechanism for handling error output.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
- Free Software Foundation, Inc.
- Contributed by Jason Merrill (jason@cygnus.com)
-
- This file is part of GNU CC.
-
-GNU CC 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,
-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
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#include "config.h"
-#include "system.h"
-#include "tree.h"
-#include "cp-tree.h"
-#include "toplev.h"
-
-/* Whether or not we should try to be quiet for errors and warnings; this is
- used to avoid being too talkative about problems with tentative choices
- when we're computing the conversion costs for a method call. */
-int cp_silent = 0;
-
-typedef void errorfn (); /* deliberately vague */
-
-static void cp_thing PARAMS ((errorfn *, int, const char *, va_list));
-
-#define STRDUP(f) (ap = (char *) alloca (strlen (f) +1), strcpy (ap, (f)), ap)
-
-/* This function supports only `%s', `%d', `%%', and the C++ print
- codes. */
-
-static void
-cp_thing (errfn, atarg1, format, ap)
- errorfn *errfn;
- int atarg1;
- const char *format;
- va_list ap;
-{
- static char *buf;
- static long buflen;
- int nargs = 0;
- long len;
- long offset;
- const char *f;
- tree atarg = 0;
-
- len = strlen (format) + 1;
- if (len > buflen)
- {
- buflen = len;
- buf = xrealloc (buf, buflen);
- }
- offset = 0;
-
- for (f = format; *f; ++f)
- {
- cp_printer * function;
- int alternate;
- int maybe_here;
-
- /* ignore text */
- if (*f != '%')
- {
- buf[offset++] = *f;
- continue;
- }
-
- ++f;
-
- alternate = 0;
- maybe_here = 0;
-
- /* Check for '+' and '#' (in that order). */
- if (*f == '+')
- {
- maybe_here = 1;
- ++f;
- }
- if (*f == '#')
- {
- alternate = 1;
- ++f;
- }
-
- /* no field width or precision */
-
- function = cp_printers[(int)*f];
-
- if (function || *f == 's')
- {
- const char *p;
- int plen;
-
- if (*f == 's')
- {
- p = va_arg (ap, char *);
- nargs++;
- }
- else
- {
- tree t = va_arg (ap, tree);
- nargs++;
-
- /* This indicates that ATARG comes from a different
- location than normal. */
- if (maybe_here && atarg1)
- atarg = t;
-
- /* If atarg1 is set and this is the first argument, then
- set ATARG appropriately. */
- if (atarg1 && nargs == 1)
- atarg = t;
-
- p = (*function) (t, alternate);
- }
-
- plen = strlen (p);
- len += plen;
- if (len > buflen)
- {
- buflen = len;
- buf = xrealloc (buf, len);
- }
- strcpy (buf + offset, p);
- offset += plen;
- }
- else if (*f == '%')
- {
- /* A `%%' has occurred in the input string. Replace it with
- a `%' in the formatted message buf. */
-
- if (++len > buflen)
- {
- buflen = len;
- buf = xrealloc (buf, len);
- }
- buf[offset++] = '%';
- }
- else
- {
- if (*f != 'd')
- abort ();
- len += HOST_BITS_PER_INT / 2;
- if (len > buflen)
- {
- buflen = len;
- buf = xrealloc (buf, len);
- }
- sprintf (buf + offset, "%d", va_arg (ap, int));
- nargs++;
- offset += strlen (buf + offset);
- /* With an ANSI C library one could write
- out += sprintf (...); */
- }
- }
- buf[offset] = '\0';
-
- /* If ATARG1 is set, but we haven't extracted any arguments, then
- extract one tree argument for ATARG. */
- if (nargs == 0 && atarg1)
- atarg = va_arg (ap, tree);
-
- if (atarg)
- {
- const char *file = cp_file_of (atarg);
- int line = cp_line_of (atarg);
- (*errfn) (file, line, "%s", buf);
- }
- else
- (*errfn) ("%s", buf);
-
-}
-
-void
-cp_error VPARAMS ((const char *format, ...))
-{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
-
- if (! cp_silent)
- cp_thing ((errorfn *) error, 0, format, ap);
- VA_CLOSE (ap);
-}
-
-void
-cp_warning VPARAMS ((const char *format, ...))
-{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
-
- if (! cp_silent)
- cp_thing ((errorfn *) warning, 0, format, ap);
- VA_CLOSE (ap);
-}
-
-void
-cp_pedwarn VPARAMS ((const char *format, ...))
-{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
-
- if (! cp_silent)
- cp_thing ((errorfn *) pedwarn, 0, format, ap);
- VA_CLOSE (ap);
-}
-
-void
-cp_compiler_error VPARAMS ((const char *format, ...))
-{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
-
- if (! cp_silent)
- cp_thing ((errorfn *) compiler_error, 0, format, ap);
- VA_CLOSE (ap);
-}
-
-void
-cp_deprecated (msg)
- const char *msg;
-{
- extern int warn_deprecated;
- if (!warn_deprecated)
- return;
- cp_warning ("%s is deprecated, please see the documentation for details", msg);
-}
-
-void
-cp_sprintf VPARAMS ((const char *format, ...))
-{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
-
- cp_thing ((errorfn *) sprintf, 0, format, ap);
- VA_CLOSE (ap);
-}
-
-void
-cp_error_at VPARAMS ((const char *format, ...))
-{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
-
- if (! cp_silent)
- cp_thing ((errorfn *) error_with_file_and_line, 1, format, ap);
- VA_CLOSE (ap);
-}
-
-void
-cp_warning_at VPARAMS ((const char *format, ...))
-{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
-
- if (! cp_silent)
- cp_thing ((errorfn *) warning_with_file_and_line, 1, format, ap);
- VA_CLOSE (ap);
-}
-
-void
-cp_pedwarn_at VPARAMS ((const char *format, ...))
-{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
-
- if (! cp_silent)
- cp_thing ((errorfn *) pedwarn_with_file_and_line, 1, format, ap);
- VA_CLOSE (ap);
-}
#include "real.h"
#include "obstack.h"
#include "toplev.h"
+#include "flags.h"
#include "diagnostic.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__)
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 int cp_printer PARAMS ((output_buffer *));
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 void print_integer PARAMS ((output_buffer *, HOST_WIDE_INT));
+static tree locate_error PARAMS ((const char *, va_list));
void
init_error ()
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);
}
/* 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)
+cp_printer (buffer)
output_buffer *buffer;
{
- int be_verbose = 0;
- tree_formatting_info tfi;
-
- memset (&tfi, 0, sizeof (tree_formatting_info));
+ 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) == '#')
{
- be_verbose = 1;
+ verbose = 1;
++output_buffer_text_cursor (buffer);
}
switch (*output_buffer_text_cursor (buffer))
{
- 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;
}
+ output_add_string (buffer, result);
return 1;
-}
-
-/* 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__));
-{
+#undef next_tree
+#undef next_tcode
+#undef next_lang
+#undef next_int
}
static void
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;
-{
- 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)
+print_non_consecutive_character (buffer, c)
output_buffer *buffer;
- tfi_t tfi;
+ int c;
{
- 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;
-
- default:
- sorry_for_unsupported_tree (t);
- /* fall throught */
+/* These are temporary wrapper functions which handle the historic
+ behavior of cp_*_at. */
- 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 (msgid, ap)
+ 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);
-
- 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);
+ if (here == 0)
+ here = va_arg (ap, tree);
- 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_context dc;
- 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__));
-{
+ set_diagnostic_context (&dc, msgid, &ap,
+ cp_file_of (here),
+ cp_line_of (here), /* warning = */ 0);
+ report_diagnostic (&dc);
+ 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;
+ tree here;
+ diagnostic_context dc;
- if (CLASS_TYPE_P (t) && !(flags & TFF_CLASS_SCOPE))
- return;
-
- 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;
+ set_diagnostic_context (&dc, msgid, &ap,
+ cp_file_of (here),
+ cp_line_of (here), /* warning = */ 1);
+ report_diagnostic (&dc);
+ 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_context dc;
-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);
+ set_diagnostic_context (&dc, msgid, &ap,
+ cp_file_of (here),
+ cp_line_of (here),
+ /* warning = */ !flag_pedantic_errors);
+ report_diagnostic (&dc);
+ VA_CLOSE (ap);
}