pretty-print.h (PP_NL_ARGMAX): New.

gcc:
	* pretty-print.h (PP_NL_ARGMAX): New.
	(text_info): Add locus.
	(struct chunk_info): New.
	(output_buffer): Add formatted_obstack, chunk_obstack, and
	cur_chunk_array. Change obstack to a pointer.
	(pp_wrapping_mode_t, pp_wrapping_mode, pp_set_verbatim_wrapping): New.
	(struct pretty_print_info): Replace ideal_maximum_length and
	prefixing_rule with wrapping.
	(pp_line_cutoff, pp_prefixing_rule): Update to match.
	Update prototypes and wrapper macros throughout.
	* pretty-print.c (pp_formatted_text_data, pp_append_r)
	(pp_base_clear_output_area, pp_construct, pp_base_formatted_text)
	(pp_base_last_position_in_text, pp_base_newline, pp_base_character):
	Update for changes to pp structure.
	(pp_base_prepare_to_format, pp_base_format_text): Delete.
	(pp_base_format, pp_base_output_formatted_text): New functions.
	(pp_base_format_verbatim): Use pp_set_verbatim_wrapping.
	(pp_verbatim): Clear text.locus.
	(pp_printf): Likewise.  Use pp_format and pp_output_formatted_text.
	* c-objc-common.c (c_tree_printer): Update function signature.
	* diagnostic.c (diagnostic_initialize): Update for changes to
	pp structure.
	(diagnostic_report_diagnostic): Call pp_format and then
	pp_output_formatted_text.
	(verbatim): Clear text.locus.
	* diagnostic.h (diagnostic_prefixing_rule, diagnostic_line_cutoff):
	Update for changes to pp structure.

	* c-lang.c: No need to include c-pretty-print.h.
	* Makefile.in: Remove bogus line containing only a tab.
	(c-lang.o): Update dependencies.
	* toplev.c (announce_function): Don't use verbatim.
	(default_tree_printer): Update signature.

	* objc/objc-lang.c: No need to include c-pretty-print.h.
	* objc/Make-lang.in: Update dependencies.

gcc/cp:
	* cp-lang.c: No need to include cxx-pretty-print.h.
	* error.c (cp_printer): Update signature.  No need to process
	flags.
	(print_instantiation_partial_context): Output last newline
	with pp_base_newline.
	* Make-lang.in: Update dependencies.

gcc/objcp:
	* objcp-lang.c: No need to include cxx-pretty-print.h.
	* Make-lang.in: Update dependencies.

Co-Authored-By: Jakub Jelinek <jakub@redhat.com>

From-SVN: r101481
This commit is contained in:
Zack Weinberg 2005-06-30 23:09:06 +00:00 committed by Zack Weinberg
parent a3648cfc0c
commit 39ce81c9c5
18 changed files with 529 additions and 209 deletions

View file

@ -1,3 +1,43 @@
2005-06-30 Zack Weinberg <zack@codesourcery.com>
Jakub Jelinek <jakub@redhat.com>
* pretty-print.h (PP_NL_ARGMAX): New.
(text_info): Add locus.
(struct chunk_info): New.
(output_buffer): Add formatted_obstack, chunk_obstack, and
cur_chunk_array. Change obstack to a pointer.
(pp_wrapping_mode_t, pp_wrapping_mode, pp_set_verbatim_wrapping): New.
(struct pretty_print_info): Replace ideal_maximum_length and
prefixing_rule with wrapping.
(pp_line_cutoff, pp_prefixing_rule): Update to match.
Update prototypes and wrapper macros throughout.
* pretty-print.c (pp_formatted_text_data, pp_append_r)
(pp_base_clear_output_area, pp_construct, pp_base_formatted_text)
(pp_base_last_position_in_text, pp_base_newline, pp_base_character):
Update for changes to pp structure.
(pp_base_prepare_to_format, pp_base_format_text): Delete.
(pp_base_format, pp_base_output_formatted_text): New functions.
(pp_base_format_verbatim): Use pp_set_verbatim_wrapping.
(pp_verbatim): Clear text.locus.
(pp_printf): Likewise. Use pp_format and pp_output_formatted_text.
* c-objc-common.c (c_tree_printer): Update function signature.
* diagnostic.c (diagnostic_initialize): Update for changes to
pp structure.
(diagnostic_report_diagnostic): Call pp_format and then
pp_output_formatted_text.
(verbatim): Clear text.locus.
* diagnostic.h (diagnostic_prefixing_rule, diagnostic_line_cutoff):
Update for changes to pp structure.
* c-lang.c: No need to include c-pretty-print.h.
* Makefile.in: Remove bogus line containing only a tab.
(c-lang.o): Update dependencies.
* toplev.c (announce_function): Don't use verbatim.
(default_tree_printer): Update signature.
* objc/objc-lang.c: No need to include c-pretty-print.h.
* objc/Make-lang.in: Update dependencies.
2005-06-29 Daniel Berlin <dberlin@dberlin.org>
* tree-complex.c (complex_variable_components): Now a hashtable.

View file

@ -1216,7 +1216,6 @@ stamp-as: $(ORIGINAL_AS_FOR_TARGET)
chmod +x as ;; \
esac
echo timestamp > $@
stamp-collect-ld: $(ORIGINAL_LD_FOR_TARGET)
@echo creating collect-ld; rm -f collect-ld; \
@ -1452,7 +1451,7 @@ c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) toplev.h $(TM_P_H) langhooks.h $(GGC_H) $(TREE_FLOW_H) \
$(TREE_GIMPLE_H) tree-iterator.h
c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(C_TREE_H) $(C_PRETTY_PRINT_H) $(DIAGNOSTIC_H) \
$(C_TREE_H) $(DIAGNOSTIC_H) \
$(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-c.h \
c-objc-common.h $(C_PRAGMA_H) c-common.def tree-inline.h
stub-objc.o : stub-objc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \

View file

@ -32,7 +32,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "langhooks-def.h"
#include "tree-inline.h"
#include "diagnostic.h"
#include "c-pretty-print.h"
#include "c-objc-common.h"
#include "c-pragma.h"

View file

@ -40,7 +40,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "target.h"
#include "c-objc-common.h"
static bool c_tree_printer (pretty_printer *, text_info *);
static bool c_tree_printer (pretty_printer *, text_info *, const char *,
int, bool, bool, bool);
bool
c_missing_noreturn_ok_p (tree decl)
@ -160,7 +161,8 @@ c_objc_common_init (void)
Please notice when called, the `%' part was already skipped by the
diagnostic machinery. */
static bool
c_tree_printer (pretty_printer *pp, text_info *text)
c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
int precision, bool wide, bool plus, bool hash)
{
tree t = va_arg (*text->args_ptr, tree);
tree name;
@ -168,7 +170,11 @@ c_tree_printer (pretty_printer *pp, text_info *text)
c_pretty_printer *cpp = (c_pretty_printer *) pp;
pp->padding = pp_none;
switch (*text->format_spec)
/* FUTURE: %+x should set the locus. */
if (precision != 0 || wide || plus || hash)
return false;
switch (*spec)
{
case 'D':
if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))

View file

@ -1,3 +1,13 @@
2005-06-30 Zack Weinberg <zack@codesourcery.com>
Jakub Jelinek <jakub@redhat.com>
* cp-lang.c: No need to include cxx-pretty-print.h.
* error.c (cp_printer): Update signature. No need to process
flags.
(print_instantiation_partial_context): Output last newline
with pp_base_newline.
* Make-lang.in: Update dependencies.
2005-06-30 Steven Bosscher <stevenb@suse.de>
* decl.c (start_decl): Replace DECL_THREAD_LOCAL with

View file

@ -236,7 +236,7 @@ CXX_PRETTY_PRINT_H = cp/cxx-pretty-print.h $(C_PRETTY_PRINT_H)
cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) flags.h \
c-pragma.h toplev.h output.h input.h cp/operators.def $(TM_P_H)
cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h debug.h langhooks.h \
$(LANGHOOKS_DEF_H) c-common.h gtype-cp.h $(CXX_PRETTY_PRINT_H) \
$(LANGHOOKS_DEF_H) c-common.h gtype-cp.h \
$(DIAGNOSTIC_H) cp/cp-objcp-common.h
cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) flags.h cp/decl.h \
output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \

View file

@ -30,7 +30,6 @@ Boston, MA 02110-1301, USA. */
#include "langhooks.h"
#include "langhooks-def.h"
#include "diagnostic.h"
#include "cxx-pretty-print.h"
#include "debug.h"
#include "cp-objcp-common.h"

View file

@ -86,7 +86,8 @@ 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 (pretty_printer *, text_info *);
static bool cp_printer (pretty_printer *, text_info *, const char *,
int, bool, bool, bool);
static tree locate_error (const char *, va_list);
static location_t location_of (tree);
@ -2228,8 +2229,9 @@ print_instantiation_partial_context (diagnostic_context *context,
TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
loc = TINST_LOCATION (t);
}
pp_verbatim (context->printer, "%s:%d: instantiated from here\n",
pp_verbatim (context->printer, "%s:%d: instantiated from here",
xloc.file, xloc.line);
pp_base_newline (context->printer);
}
/* Called from cp_thing to print the template context for an error. */
@ -2266,24 +2268,23 @@ print_instantiation_context (void)
%T type.
%V cv-qualifier. */
static bool
cp_printer (pretty_printer *pp, text_info *text)
cp_printer (pretty_printer *pp, text_info *text, const char *spec,
int precision, bool wide, bool set_locus, bool verbose)
{
int verbose = 0;
const char *result;
#define next_tree va_arg (*text->args_ptr, tree)
tree t = NULL;
#define next_tree (t = 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 == '#')
{
verbose = 1;
++text->format_spec;
}
if (precision != 0 || wide)
return false;
switch (*text->format_spec)
if (text->locus == NULL)
set_locus = false;
switch (*spec)
{
case 'A': result = args_to_string (next_tree, verbose); break;
case 'C': result = code_to_string (next_tcode); break;
@ -2302,6 +2303,8 @@ cp_printer (pretty_printer *pp, text_info *text)
}
pp_base_string (pp, result);
if (set_locus && t != NULL)
*text->locus = location_of (t);
return true;
#undef next_tree
#undef next_tcode

View file

@ -97,7 +97,7 @@ diagnostic_initialize (diagnostic_context *context)
/* By default, diagnostics are sent to stderr. */
context->printer->buffer->stream = stderr;
/* By default, we emit prefixes once per message. */
context->printer->prefixing_rule = DIAGNOSTICS_SHOW_PREFIX_ONCE;
context->printer->wrapping.rule = DIAGNOSTICS_SHOW_PREFIX_ONCE;
memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
context->issue_warnings_are_errors_message = true;
@ -347,10 +347,10 @@ diagnostic_report_diagnostic (diagnostic_context *context,
= ACONCAT ((diagnostic->message.format_spec,
" [", cl_options[diagnostic->option_index].opt_text, "]", NULL));
pp_prepare_to_format (context->printer, &diagnostic->message,
&diagnostic->location);
diagnostic->message.locus = &diagnostic->location;
pp_format (context->printer, &diagnostic->message);
(*diagnostic_starter (context)) (context, diagnostic);
pp_format_text (context->printer, &diagnostic->message);
pp_output_formatted_text (context->printer);
(*diagnostic_finalizer (context)) (context, diagnostic);
pp_flush (context->printer);
diagnostic_action_after_output (context, diagnostic);
@ -405,6 +405,7 @@ verbatim (const char *gmsgid, ...)
text.err_no = errno;
text.args_ptr = &ap;
text.format_spec = _(gmsgid);
text.locus = NULL;
pp_format_verbatim (global_dc->printer, &text);
pp_flush (global_dc->printer);
va_end (ap);

View file

@ -120,11 +120,11 @@ struct diagnostic_context
#define diagnostic_format_decoder(DC) ((DC)->printer->format_decoder)
/* Same as output_prefixing_rule. Works on 'diagnostic_context *'. */
#define diagnostic_prefixing_rule(DC) ((DC)->printer->prefixing_rule)
#define diagnostic_prefixing_rule(DC) ((DC)->printer->wrapping.rule)
/* Maximum characters per line in automatic line wrapping mode.
Zero means don't wrap lines. */
#define diagnostic_line_cutoff(DC) ((DC)->printer->ideal_maximum_length)
#define diagnostic_line_cutoff(DC) ((DC)->printer->wrapping.line_cutoff)
#define diagnostic_flush_buffer(DC) pp_base_flush ((DC)->printer)

View file

@ -69,7 +69,7 @@ cc1obj$(exeext): $(OBJC_OBJS) $(C_AND_OBJC_OBJS) cc1obj-checksum.o $(BACKEND) $(
objc/objc-lang.o : objc/objc-lang.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(C_TREE_H) $(C_PRETTY_PRINT_H) $(DIAGNOSTIC_H) \
$(C_TREE_H) $(DIAGNOSTIC_H) \
$(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-objc.h \
c-objc-common.h objc/objc-act.h tree-gimple.h

View file

@ -31,7 +31,6 @@ Boston, MA 02110-1301, USA. */
#include "langhooks.h"
#include "langhooks-def.h"
#include "diagnostic.h"
#include "c-pretty-print.h"
#include "c-objc-common.h"
enum c_language_kind c_language = clk_objc;

View file

@ -1,3 +1,9 @@
2005-06-30 Zack Weinberg <zack@codesourcery.com>
Jakub Jelinek <jakub@redhat.com>
* objcp-lang.c: No need to include cxx-pretty-print.h.
* Make-lang.in: Update dependencies.
2005-06-25 Kelley Cook <kcook@gcc.gnu.org>
* all files: Update FSF in copyright headers.

View file

@ -69,7 +69,7 @@ cc1objplus$(exeext): $(OBJCXX_OBJS) cc1objplus-checksum.o $(BACKEND) $(LIBDEPS)
objcp/objcp-lang.o : objcp/objcp-lang.c \
$(CXX_TREE_H) $(TM_H) toplev.h debug.h langhooks.h objc/objc-act.h \
$(LANGHOOKS_DEF_H) c-common.h gtype-objcp.h $(CXX_PRETTY_PRINT_H) \
$(LANGHOOKS_DEF_H) c-common.h gtype-objcp.h \
$(DIAGNOSTIC_H) cp/cp-objcp-common.h tree-gimple.h
objcp/objcp-decl.o : objcp/objcp-decl.c \

View file

@ -31,7 +31,6 @@ Boston, MA 02110-1301, USA. */
#include "langhooks.h"
#include "langhooks-def.h"
#include "diagnostic.h"
#include "cxx-pretty-print.h"
#include "debug.h"
#include "cp-objcp-common.h"

View file

@ -33,7 +33,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
/* A pointer to the formatted diagnostic message. */
#define pp_formatted_text_data(PP) \
((const char *) obstack_base (&pp_base (PP)->buffer->obstack))
((const char *) obstack_base (pp_base (PP)->buffer->obstack))
/* Format an integer given by va_arg (ARG, type-specifier T) where
type-specifier is a precision modifier as indicated by PREC. F is
@ -149,7 +149,7 @@ pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end)
static inline void
pp_append_r (pretty_printer *pp, const char *start, int length)
{
obstack_grow (&pp->buffer->obstack, start, length);
obstack_grow (pp->buffer->obstack, start, length);
pp->buffer->line_length += length;
}
@ -166,42 +166,7 @@ pp_base_indent (pretty_printer *pp)
pp_space (pp);
}
/* Prepare PP to format a message pointed to by TEXT, with tentative
location LOCUS. It is expected that a call to pp_format_text with
exactly the same PP and TEXT arguments will follow. This routine
may modify the data in memory at TEXT and LOCP, and if it does,
caller is expected to notice.
Currently, all this does is notice a %H or %J escape at the beginning
of the string, and update LOCUS to match. */
void
pp_base_prepare_to_format (pretty_printer *pp ATTRIBUTE_UNUSED,
text_info *text,
location_t *locus)
{
const char *p = text->format_spec;
tree t;
/* Extract the location information if any. */
if (p[0] == '%')
switch (p[1])
{
case 'H':
*locus = *va_arg (*text->args_ptr, location_t *);
text->format_spec = p + 2;
break;
case 'J':
t = va_arg (*text->args_ptr, tree);
*locus = DECL_SOURCE_LOCATION (t);
text->format_spec = p + 2;
break;
}
}
/* Format a message pointed to by TEXT. The following format specifiers are
recognized as being client independent:
/* The following format specifiers are recognized as being client independent:
%d, %i: (signed) integer in base ten.
%u: unsigned integer in base ten.
%o: unsigned integer in base eight.
@ -218,59 +183,245 @@ pp_base_prepare_to_format (pretty_printer *pp ATTRIBUTE_UNUSED,
%>: closing quote.
%': apostrophe (should only be used in untranslated messages;
translations should use appropriate punctuation directly).
%.*s: a substring the length of which is specified by an integer.
%.*s: a substring the length of which is specified by an argument
integer.
%Ns: likewise, but length specified as constant in the format string.
%H: location_t.
Flag 'q': quote formatted text (must come immediately after '%'). */
%J: a decl tree, from which DECL_SOURCE_LOCATION will be recorded.
Flag 'q': quote formatted text (must come immediately after '%').
Arguments can be used sequentially, or through %N$ resp. *N$
notation Nth argument after the format string. If %N$ / *N$
notation is used, it must be used for all arguments, except %m, %%,
%<, %> and %', which may not have a number, as they do not consume
an argument. When %M$.*N$s is used, M must be N + 1. (This may
also be written %M$.*s, provided N is not otherwise used.) The
format string must have conversion specifiers with argument numbers
1 up to highest argument; each argument may only be used once.
A format string can have at most 30 arguments. */
/* Formatting phases 1 and 2: render TEXT->format_spec plus
TEXT->args_ptr into a series of chunks in PP->buffer->args[].
Phase 3 is in pp_base_format_text. */
void
pp_base_format_text (pretty_printer *pp, text_info *text)
pp_base_format (pretty_printer *pp, text_info *text)
{
for (; *text->format_spec; ++text->format_spec)
output_buffer *buffer = pp->buffer;
const char *p;
const char **args;
struct chunk_info *new_chunk_array;
unsigned int curarg = 0, chunk = 0, argno;
pp_wrapping_mode_t old_wrapping_mode;
bool any_unnumbered = false, any_numbered = false;
const char **formatters[PP_NL_ARGMAX];
/* Allocate a new chunk structure. */
new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info);
new_chunk_array->prev = buffer->cur_chunk_array;
buffer->cur_chunk_array = new_chunk_array;
args = new_chunk_array->args;
/* Formatting phase 1: split up TEXT->format_spec into chunks in
PP->buffer->args[]. Even-numbered chunks are to be output
verbatim, odd-numbered chunks are format specifiers.
%m, %%, %<, %>, and %' are replaced with the appropriate text at
this point. */
memset (formatters, 0, sizeof formatters);
for (p = text->format_spec; *p; )
{
while (*p != '\0' && *p != '%')
{
obstack_1grow (&buffer->chunk_obstack, *p);
p++;
}
if (*p == '\0')
break;
switch (*++p)
{
case '\0':
gcc_unreachable ();
case '%':
obstack_1grow (&buffer->chunk_obstack, '%');
p++;
continue;
case '<':
obstack_grow (&buffer->chunk_obstack,
open_quote, strlen (open_quote));
p++;
continue;
case '>':
case '\'':
obstack_grow (&buffer->chunk_obstack,
open_quote, strlen (close_quote));
p++;
continue;
case 'm':
{
const char *errstr = xstrerror (text->err_no);
obstack_grow (&buffer->chunk_obstack, errstr, strlen (errstr));
}
p++;
continue;
default:
/* Handled in phase 2. Terminate the plain chunk here. */
obstack_1grow (&buffer->chunk_obstack, '\0');
gcc_assert (chunk < PP_NL_ARGMAX * 2);
args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
break;
}
if (ISDIGIT (*p))
{
char *end;
argno = strtoul (p, &end, 10) - 1;
p = end;
gcc_assert (*p == '$');
p++;
any_numbered = true;
gcc_assert (!any_unnumbered);
}
else
{
argno = curarg++;
any_unnumbered = true;
gcc_assert (!any_numbered);
}
gcc_assert (argno < PP_NL_ARGMAX);
gcc_assert (!formatters[argno]);
formatters[argno] = &args[chunk];
do
{
obstack_1grow (&buffer->chunk_obstack, *p);
p++;
}
while (strchr ("qwl+#", p[-1]));
if (p[-1] == '.')
{
/* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
(where M == N + 1). */
if (ISDIGIT (*p))
{
do
{
obstack_1grow (&buffer->chunk_obstack, *p);
p++;
}
while (ISDIGIT (p[-1]));
gcc_assert (p[-1] == 's');
}
else
{
gcc_assert (*p == '*');
obstack_1grow (&buffer->chunk_obstack, '*');
p++;
if (ISDIGIT (*p))
{
char *end;
unsigned int argno2 = strtoul (p, &end, 10) - 1;
p = end;
gcc_assert (argno2 == argno - 1);
gcc_assert (!any_unnumbered);
gcc_assert (*p == '$');
p++;
formatters[argno2] = formatters[argno];
}
else
{
gcc_assert (!any_numbered);
formatters[argno+1] = formatters[argno];
curarg++;
}
gcc_assert (*p == 's');
obstack_1grow (&buffer->chunk_obstack, 's');
p++;
}
}
if (*p == '\0')
break;
obstack_1grow (&buffer->chunk_obstack, '\0');
gcc_assert (chunk < PP_NL_ARGMAX * 2);
args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
}
obstack_1grow (&buffer->chunk_obstack, '\0');
gcc_assert (chunk < PP_NL_ARGMAX * 2);
args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
args[chunk] = 0;
/* Set output to the argument obstack, and switch line-wrapping and
prefixing off. */
buffer->obstack = &buffer->chunk_obstack;
old_wrapping_mode = pp_set_verbatim_wrapping (pp);
/* Second phase. Replace each formatter with the formatted text it
corresponds to. */
for (argno = 0; formatters[argno]; argno++)
{
int precision = 0;
bool wide = false;
bool quoted = false;
bool plus = false;
bool hash = false;
bool quote = false;
/* Ignore text. */
{
const char *p = text->format_spec;
while (*p && *p != '%')
++p;
pp_wrap_text (pp, text->format_spec, p);
text->format_spec = p;
}
/* We do not attempt to enforce any ordering on the modifier
characters. */
if (*text->format_spec == '\0')
break;
/* We got a '%'. Check for 'q', then parse precision modifiers,
if any. */
if (*++text->format_spec == 'q')
for (p = *formatters[argno];; p++)
{
quoted = true;
++text->format_spec;
switch (*p)
{
case 'q':
gcc_assert (!quote);
quote = true;
continue;
case '+':
gcc_assert (!plus);
plus = true;
continue;
case '#':
gcc_assert (!hash);
hash = true;
continue;
case 'w':
gcc_assert (!wide);
wide = true;
continue;
case 'l':
/* We don't support precision beyond that of "long long". */
gcc_assert (precision < 2);
precision++;
continue;
}
break;
}
switch (*text->format_spec)
{
case 'w':
wide = true;
++text->format_spec;
break;
case 'l':
do
++precision;
while (*++text->format_spec == 'l');
break;
gcc_assert (!wide || precision == 0);
default:
break;
}
/* We don't support precision beyond that of "long long". */
gcc_assert (precision <= 2);
if (quoted)
if (quote)
pp_string (pp, open_quote);
switch (*text->format_spec)
switch (*p)
{
case 'c':
pp_character (pp, va_arg (*text->args_ptr, int));
@ -278,87 +429,92 @@ pp_base_format_text (pretty_printer *pp, text_info *text)
case 'd':
case 'i':
if (wide)
pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
else
pp_integer_with_precision
(pp, *text->args_ptr, precision, int, "d");
if (wide)
pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
else
pp_integer_with_precision
(pp, *text->args_ptr, precision, int, "d");
break;
case 'o':
if (wide)
pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
else
pp_integer_with_precision
(pp, *text->args_ptr, precision, unsigned, "u");
if (wide)
pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
else
pp_integer_with_precision
(pp, *text->args_ptr, precision, unsigned, "o");
break;
case 's':
pp_string (pp, va_arg (*text->args_ptr, const char *));
break;
case 'p':
pp_pointer (pp, va_arg (*text->args_ptr, void *));
break;
case 'p':
pp_pointer (pp, va_arg (*text->args_ptr, void *));
break;
case 'u':
if (wide)
pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
else
pp_integer_with_precision
(pp, *text->args_ptr, precision, unsigned, "u");
if (wide)
pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
else
pp_integer_with_precision
(pp, *text->args_ptr, precision, unsigned, "u");
break;
case 'x':
if (wide)
pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
else
pp_integer_with_precision
(pp, *text->args_ptr, precision, unsigned, "x");
if (wide)
pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
else
pp_integer_with_precision
(pp, *text->args_ptr, precision, unsigned, "x");
break;
case 'm':
pp_string (pp, xstrerror (text->err_no));
case 'H':
{
location_t *locus = va_arg (*text->args_ptr, location_t *);
gcc_assert (text->locus != NULL);
*text->locus = *locus;
}
break;
case '%':
pp_character (pp, '%');
case 'J':
{
tree t = va_arg (*text->args_ptr, tree);
gcc_assert (text->locus != NULL);
*text->locus = DECL_SOURCE_LOCATION (t);
}
break;
case '<':
pp_string (pp, open_quote);
break;
case '>':
case '\'':
pp_string (pp, close_quote);
break;
case 'H':
{
location_t *locus = va_arg (*text->args_ptr, location_t *);
expanded_location s = expand_location (*locus);
pp_string (pp, "file '");
pp_string (pp, s.file);
pp_string (pp, "', line ");
pp_decimal_int (pp, s.line);
}
break;
case '.':
{
int n;
const char *s;
/* We handle no precision specifier but '%.*s'. */
++text->format_spec;
gcc_assert (*text->format_spec == '*');
++text->format_spec;
gcc_assert (*text->format_spec == 's');
n = va_arg (*text->args_ptr, int);
/* We handle '%.Ns' and '%.*s' or '%M$.*N$s'
(where M == N + 1). The format string should be verified
already from the first phase. */
p++;
if (ISDIGIT (*p))
{
char *end;
n = strtoul (p, &end, 10);
p = end;
gcc_assert (*p == 's');
}
else
{
gcc_assert (*p == '*');
p++;
gcc_assert (*p == 's');
n = va_arg (*text->args_ptr, int);
/* This consumes a second entry in the formatters array. */
gcc_assert (formatters[argno] == formatters[argno+1]);
argno++;
}
s = va_arg (*text->args_ptr, const char *);
pp_append_text (pp, s, s + n);
}
@ -367,15 +523,54 @@ pp_base_format_text (pretty_printer *pp, text_info *text)
default:
{
bool ok;
gcc_assert (pp_format_decoder (pp));
ok = pp_format_decoder (pp) (pp, text);
ok = pp_format_decoder (pp) (pp, text, p,
precision, wide, plus, hash);
gcc_assert (ok);
}
}
if (quoted)
if (quote)
pp_string (pp, close_quote);
obstack_1grow (&buffer->chunk_obstack, '\0');
*formatters[argno] = XOBFINISH (&buffer->chunk_obstack, const char *);
}
#ifdef ENABLE_CHECKING
for (; argno < PP_NL_ARGMAX; argno++)
gcc_assert (!formatters[argno]);
#endif
/* Revert to normal obstack and wrapping mode. */
buffer->obstack = &buffer->formatted_obstack;
buffer->line_length = 0;
pp_wrapping_mode (pp) = old_wrapping_mode;
pp_clear_state (pp);
}
/* Format of a message pointed to by TEXT. */
void
pp_base_output_formatted_text (pretty_printer *pp)
{
unsigned int chunk;
output_buffer *buffer = pp_buffer (pp);
struct chunk_info *chunk_array = buffer->cur_chunk_array;
const char **args = chunk_array->args;
gcc_assert (buffer->obstack == &buffer->formatted_obstack);
gcc_assert (buffer->line_length == 0);
/* This is a third phase, first 2 phases done in pp_base_format_args.
Now we actually print it. */
for (chunk = 0; args[chunk]; chunk++)
pp_string (pp, args[chunk]);
/* Deallocate the chunk structure and everything after it (i.e. the
associated series of formatted strings). */
buffer->cur_chunk_array = chunk_array->prev;
obstack_free (&buffer->chunk_obstack, chunk_array);
}
/* Helper subroutine of output_verbatim and verbatim. Do the appropriate
@ -383,17 +578,15 @@ pp_base_format_text (pretty_printer *pp, text_info *text)
void
pp_base_format_verbatim (pretty_printer *pp, text_info *text)
{
diagnostic_prefixing_rule_t rule = pp_prefixing_rule (pp);
int line_cutoff = pp_line_cutoff (pp);
/* Set verbatim mode. */
pp->prefixing_rule = DIAGNOSTICS_SHOW_PREFIX_NEVER;
pp_line_cutoff (pp) = 0;
pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp);
/* Do the actual formatting. */
pp_format_text (pp, text);
pp_format (pp, text);
pp_output_formatted_text (pp);
/* Restore previous settings. */
pp_prefixing_rule (pp) = rule;
pp_line_cutoff (pp) = line_cutoff;
pp_wrapping_mode (pp) = oldmode;
}
/* Flush the content of BUFFER onto the attached stream. */
@ -421,7 +614,7 @@ pp_base_set_line_maximum_length (pretty_printer *pp, int length)
void
pp_base_clear_output_area (pretty_printer *pp)
{
obstack_free (&pp->buffer->obstack, obstack_base (&pp->buffer->obstack));
obstack_free (pp->buffer->obstack, obstack_base (pp->buffer->obstack));
pp->buffer->line_length = 0;
}
@ -485,7 +678,9 @@ pp_construct (pretty_printer *pp, const char *prefix, int maximum_length)
{
memset (pp, 0, sizeof (pretty_printer));
pp->buffer = xcalloc (1, sizeof (output_buffer));
obstack_init (&pp->buffer->obstack);
obstack_init (&pp->buffer->chunk_obstack);
obstack_init (&pp->buffer->formatted_obstack);
pp->buffer->obstack = &pp->buffer->formatted_obstack;
pp->buffer->stream = stderr;
pp_line_cutoff (pp) = maximum_length;
pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
@ -516,7 +711,7 @@ pp_base_append_text (pretty_printer *pp, const char *start, const char *end)
const char *
pp_base_formatted_text (pretty_printer *pp)
{
obstack_1grow (&pp->buffer->obstack, '\0');
obstack_1grow (pp->buffer->obstack, '\0');
return pp_formatted_text_data (pp);
}
@ -526,7 +721,7 @@ const char *
pp_base_last_position_in_text (const pretty_printer *pp)
{
const char *p = NULL;
struct obstack *text = &pp->buffer->obstack;
struct obstack *text = pp->buffer->obstack;
if (obstack_base (text) != obstack_next_free (text))
p = ((const char *) obstack_next_free (text)) - 1;
@ -553,7 +748,9 @@ pp_printf (pretty_printer *pp, const char *msg, ...)
text.err_no = errno;
text.args_ptr = &ap;
text.format_spec = msg;
pp_format_text (pp, &text);
text.locus = NULL;
pp_format (pp, &text);
pp_output_formatted_text (pp);
va_end (ap);
}
@ -569,6 +766,7 @@ pp_verbatim (pretty_printer *pp, const char *msg, ...)
text.err_no = errno;
text.args_ptr = &ap;
text.format_spec = msg;
text.locus = NULL;
pp_format_verbatim (pp, &text);
va_end (ap);
}
@ -579,7 +777,7 @@ pp_verbatim (pretty_printer *pp, const char *msg, ...)
void
pp_base_newline (pretty_printer *pp)
{
obstack_1grow (&pp->buffer->obstack, '\n');
obstack_1grow (pp->buffer->obstack, '\n');
pp->buffer->line_length = 0;
}
@ -594,7 +792,7 @@ pp_base_character (pretty_printer *pp, int c)
if (ISSPACE (c))
return;
}
obstack_1grow (&pp->buffer->obstack, c);
obstack_1grow (pp->buffer->obstack, c);
++pp->buffer->line_length;
}

View file

@ -25,6 +25,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "obstack.h"
#include "input.h"
/* Maximum number of format string arguments. */
#define PP_NL_ARGMAX 30
/* The type of a text to be formatted according a format specification
along with a list of things. */
typedef struct
@ -32,6 +35,7 @@ typedef struct
const char *format_spec;
va_list *args_ptr;
int err_no; /* for %m */
location_t *locus;
} text_info;
/* How often diagnostics are prefixed by their locations:
@ -46,12 +50,42 @@ typedef enum
DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE = 0x2
} diagnostic_prefixing_rule_t;
/* The chunk_info data structure forms a stack of the results from the
first phase of formatting (pp_base_format) which have not yet been
output (pp_base_output_formatted_text). A stack is necessary because
the diagnostic starter may decide to generate its own output by way
of the formatter. */
struct chunk_info
{
/* Pointer to previous chunk on the stack. */
struct chunk_info *prev;
/* Array of chunks to output. Each chunk is a NUL-terminated string.
In the first phase of formatting, even-numbered chunks are
to be output verbatim, odd-numbered chunks are format specifiers.
The second phase replaces all odd-numbered chunks with formatted
text, and the third phase simply emits all the chunks in sequence
with appropriate line-wrapping. */
const char *args[PP_NL_ARGMAX * 2];
};
/* The output buffer datatype. This is best seen as an abstract datatype
whose fields should not be accessed directly by clients. */
typedef struct
{
/* The obstack where the text is built up. */
struct obstack obstack;
/* Obstack where the text is built up. */
struct obstack formatted_obstack;
/* Obstack containing a chunked representation of the format
specification plus arguments. */
struct obstack chunk_obstack;
/* Currently active obstack: one of the above two. This is used so
that the text formatters don't need to know which phase we're in. */
struct obstack *obstack;
/* Stack of chunk arrays. These come from the chunk_obstack. */
struct chunk_info *cur_chunk_array;
/* Where to output formatted text. */
FILE *stream;
@ -72,11 +106,34 @@ typedef enum
pp_none, pp_before, pp_after
} pp_padding;
/* Structure for switching in and out of verbatim mode in a convenient
manner. */
typedef struct
{
/* Current prefixing rule. */
diagnostic_prefixing_rule_t rule;
/* The ideal upper bound of number of characters per line, as suggested
by front-end. */
int line_cutoff;
} pp_wrapping_mode_t;
/* Maximum characters per line in automatic line wrapping mode.
Zero means don't wrap lines. */
#define pp_line_cutoff(PP) pp_base (PP)->wrapping.line_cutoff
/* Prefixing rule used in formatting a diagnostic message. */
#define pp_prefixing_rule(PP) pp_base (PP)->wrapping.rule
/* Get or set the wrapping mode as a single entity. */
#define pp_wrapping_mode(PP) pp_base (PP)->wrapping
/* The type of a hook that formats client-specific data onto a pretty_pinter.
A client-supplied formatter returns true if everything goes well,
otherwise it returns false. */
typedef struct pretty_print_info pretty_printer;
typedef bool (*printer_fn) (pretty_printer *, text_info *);
typedef bool (*printer_fn) (pretty_printer *, text_info *, const char *,
int, bool, bool, bool);
/* Client supplied function used to decode formats. */
#define pp_format_decoder(PP) pp_base (PP)->format_decoder
@ -85,16 +142,9 @@ typedef bool (*printer_fn) (pretty_printer *, text_info *);
formatting. */
#define pp_needs_newline(PP) pp_base (PP)->need_newline
/* Maximum characters per line in automatic line wrapping mode.
Zero means don't wrap lines. */
#define pp_line_cutoff(PP) pp_base (PP)->ideal_maximum_length
/* True if PRETTY-PTINTER is in line-wrapping mode. */
#define pp_is_wrapping_line(PP) (pp_line_cutoff (PP) > 0)
/* Prefixing rule used in formatting a diagnostic message. */
#define pp_prefixing_rule(PP) pp_base (PP)->prefixing_rule
/* The amount of whitespace to be emitted when starting a new line. */
#define pp_indentation(PP) pp_base (PP)->indent_skip
@ -116,15 +166,11 @@ struct pretty_print_info
account the case of a very very looong prefix. */
int maximum_length;
/* The ideal upper bound of number of characters per line, as suggested
by front-end. */
int ideal_maximum_length;
/* Indentation count. */
int indent_skip;
/* Current prefixing rule. */
diagnostic_prefixing_rule_t prefixing_rule;
/* Current wrapping mode. */
pp_wrapping_mode_t wrapping;
/* If non-NULL, this function formats a TEXT into the BUFFER. When called,
TEXT->format_spec points to a format code. FORMAT_DECODER should call
@ -158,9 +204,9 @@ struct pretty_print_info
#define pp_append_text(PP, B, E) \
pp_base_append_text (pp_base (PP), B, E)
#define pp_flush(PP) pp_base_flush (pp_base (PP))
#define pp_prepare_to_format(PP, TI, LOC) \
pp_base_prepare_to_format (pp_base (PP), TI, LOC)
#define pp_format_text(PP, TI) pp_base_format_text (pp_base (PP), TI)
#define pp_format(PP, TI) pp_base_format (pp_base (PP), TI)
#define pp_output_formatted_text(PP) \
pp_base_output_formatted_text (pp_base (PP))
#define pp_format_verbatim(PP, TI) \
pp_base_format_verbatim (pp_base (PP), TI)
@ -264,9 +310,8 @@ extern void pp_printf (pretty_printer *, const char *, ...)
extern void pp_verbatim (pretty_printer *, const char *, ...)
ATTRIBUTE_GCC_PPDIAG(2,3);
extern void pp_base_flush (pretty_printer *);
extern void pp_base_prepare_to_format (pretty_printer *, text_info *,
location_t *);
extern void pp_base_format_text (pretty_printer *, text_info *);
extern void pp_base_format (pretty_printer *, text_info *);
extern void pp_base_output_formatted_text (pretty_printer *);
extern void pp_base_format_verbatim (pretty_printer *, text_info *);
extern void pp_base_indent (pretty_printer *);
@ -276,4 +321,15 @@ extern void pp_base_string (pretty_printer *, const char *);
extern void pp_write_text_to_stream (pretty_printer *pp);
extern void pp_base_maybe_space (pretty_printer *);
/* Switch into verbatim mode and return the old mode. */
static inline pp_wrapping_mode_t
pp_set_verbatim_wrapping_ (pretty_printer *pp)
{
pp_wrapping_mode_t oldmode = pp_wrapping_mode (pp);
pp_line_cutoff (pp) = 0;
pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_NEVER;
return oldmode;
}
#define pp_set_verbatim_wrapping(PP) pp_set_verbatim_wrapping_ (pp_base (PP))
#endif /* GCC_PRETTY_PRINT_H */

View file

@ -442,9 +442,9 @@ announce_function (tree decl)
if (!quiet_flag)
{
if (rtl_dump_and_exit)
verbatim ("%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
else
verbatim (" %s", lang_hooks.decl_printable_name (decl, 2));
fprintf (stderr, " %s", lang_hooks.decl_printable_name (decl, 2));
fflush (stderr);
pp_needs_newline (global_dc->printer) = true;
diagnostic_set_last_function (global_dc);
@ -1355,11 +1355,16 @@ default_pch_valid_p (const void *data_p, size_t len)
/* Default tree printer. Handles declarations only. */
static bool
default_tree_printer (pretty_printer * pp, text_info *text)
default_tree_printer (pretty_printer * pp, text_info *text, const char *spec,
int precision, bool wide, bool plus, bool hash)
{
tree t;
switch (*text->format_spec)
/* FUTURE: %+x should set the locus. */
if (precision != 0 || wide || plus || hash)
return false;
switch (*spec)
{
case 'D':
t = va_arg (*text->args_ptr, tree);