]> gcc.gnu.org Git - gcc.git/blob - gcc/diagnostic.c
diagnostic.c (diagnostic_finish): Rename to output_flush.
[gcc.git] / gcc / diagnostic.c
1 /* Language-independent diagnostic subroutines for the GNU C compiler
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22
23 /* This file implements the language independent aspect of diagnostic
24 message module. */
25
26 #include "config.h"
27 #undef FLOAT /* This is for hpux. They should change hpux. */
28 #undef FFS /* Some systems define this in param.h. */
29 #include "system.h"
30 #include "tree.h"
31 #include "tm_p.h"
32 #include "flags.h"
33 #include "input.h"
34 #include "toplev.h"
35 #include "intl.h"
36 #include "diagnostic.h"
37 #include "langhooks.h"
38 #include "langhooks-def.h"
39
40 #define obstack_chunk_alloc xmalloc
41 #define obstack_chunk_free free
42
43 #define output_formatted_integer(BUFFER, FORMAT, INTEGER) \
44 do \
45 { \
46 sprintf ((BUFFER)->digit_buffer, FORMAT, INTEGER); \
47 output_add_string (BUFFER, (BUFFER)->digit_buffer); \
48 } \
49 while (0)
50
51 #define output_text_length(BUFFER) (BUFFER)->line_length
52 #define is_starting_newline(BUFFER) (output_text_length (BUFFER) == 0)
53 #define output_prefix(BUFFER) (BUFFER)->state.prefix
54 #define line_wrap_cutoff(BUFFER) (BUFFER)->state.maximum_length
55 #define prefix_was_emitted_for(BUFFER) (BUFFER)->state.emitted_prefix_p
56 #define output_buffer_ptr_to_format_args(BUFFER) (BUFFER)->state.format_args
57
58 #define diagnostic_args output_buffer_ptr_to_format_args (diagnostic_buffer)
59 #define diagnostic_msg output_buffer_text_cursor (diagnostic_buffer)
60
61 /* Prototypes. */
62 static void output_flush PARAMS ((output_buffer *));
63 static void output_do_verbatim PARAMS ((output_buffer *,
64 const char *, va_list *));
65 static void output_buffer_to_stream PARAMS ((output_buffer *));
66 static void output_format PARAMS ((output_buffer *));
67 static void output_indent PARAMS ((output_buffer *));
68
69 static char *vbuild_message_string PARAMS ((const char *, va_list))
70 ATTRIBUTE_PRINTF (1, 0);
71 static char *build_message_string PARAMS ((const char *, ...))
72 ATTRIBUTE_PRINTF_1;
73 static void output_do_printf PARAMS ((output_buffer *, const char *))
74 ATTRIBUTE_PRINTF (2, 0);
75 static void format_with_decl PARAMS ((output_buffer *, tree));
76 static void diagnostic_for_decl PARAMS ((tree, const char *, va_list *, int));
77 static void set_real_maximum_length PARAMS ((output_buffer *));
78
79 static void output_unsigned_decimal PARAMS ((output_buffer *, unsigned int));
80 static void output_long_decimal PARAMS ((output_buffer *, long int));
81 static void output_long_unsigned_decimal PARAMS ((output_buffer *,
82 long unsigned int));
83 static void output_octal PARAMS ((output_buffer *, unsigned int));
84 static void output_long_octal PARAMS ((output_buffer *, unsigned long int));
85 static void output_hexadecimal PARAMS ((output_buffer *, unsigned int));
86 static void output_long_hexadecimal PARAMS ((output_buffer *,
87 unsigned long int));
88 static void output_append_r PARAMS ((output_buffer *, const char *, int));
89 static void wrap_text PARAMS ((output_buffer *, const char *, const char *));
90 static void maybe_wrap_text PARAMS ((output_buffer *, const char *,
91 const char *));
92 static void output_clear_data PARAMS ((output_buffer *));
93
94 static void default_diagnostic_starter PARAMS ((output_buffer *,
95 diagnostic_context *));
96 static void default_diagnostic_finalizer PARAMS ((output_buffer *,
97 diagnostic_context *));
98
99 static void error_recursion PARAMS ((void)) ATTRIBUTE_NORETURN;
100
101 extern int rtl_dump_and_exit;
102 extern int warnings_are_errors;
103
104 /* A diagnostic_context surrogate for stderr. */
105 static diagnostic_context global_diagnostic_context;
106 diagnostic_context *global_dc = &global_diagnostic_context;
107
108 /* Function of last error message;
109 more generally, function such that if next error message is in it
110 then we don't have to mention the function name. */
111 static tree last_error_function = NULL;
112
113 /* Used to detect when input_file_stack has changed since last described. */
114 static int last_error_tick;
115
116 /* Prevent recursion into the error handler. */
117 static int diagnostic_lock;
118
119 \f
120 /* Return truthvalue if current input file is different from the most recent
121 file involved in a diagnostic message. */
122
123 int
124 error_module_changed ()
125 {
126 return last_error_tick != input_file_stack_tick;
127 }
128
129 /* Remember current file as being the most recent file involved in a
130 diagnostic message. */
131
132 void
133 record_last_error_module ()
134 {
135 last_error_tick = input_file_stack_tick;
136 }
137
138 /* Same as error_module_changed, but for function. */
139
140 int
141 error_function_changed ()
142 {
143 return last_error_function != current_function_decl;
144 }
145
146 /* Same as record_last_error_module, but for function. */
147
148 void
149 record_last_error_function ()
150 {
151 last_error_function = current_function_decl;
152 }
153
154 /* Initialize the diagnostic message outputting machinery. */
155
156 void
157 diagnostic_initialize (context)
158 diagnostic_context *context;
159 {
160 memset (context, 0, sizeof *context);
161 obstack_init (&context->buffer.obstack);
162
163 /* By default, diagnostics are sent to stderr. */
164 output_buffer_attached_stream (&context->buffer) = stderr;
165
166 /* By default, we emit prefixes once per message. */
167 diagnostic_prefixing_rule (context) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
168
169 diagnostic_starter (context) = default_diagnostic_starter;
170 diagnostic_finalizer (context) = default_diagnostic_finalizer;
171 }
172
173 /* Returns true if BUFFER is in line-wrapping mode. */
174
175 int
176 output_is_line_wrapping (buffer)
177 output_buffer *buffer;
178 {
179 return output_line_cutoff (buffer) > 0;
180 }
181
182 /* Return BUFFER's prefix. */
183
184 const char *
185 output_get_prefix (buffer)
186 const output_buffer *buffer;
187 {
188 return output_prefix (buffer);
189 }
190
191 /* Subroutine of output_set_maximum_length. Set up BUFFER's
192 internal maximum characters per line. */
193
194 static void
195 set_real_maximum_length (buffer)
196 output_buffer *buffer;
197 {
198 /* If we're told not to wrap lines then do the obvious thing. In case
199 we'll emit prefix only once per diagnostic message, it is appropriate
200 not to increase unnecessarily the line-length cut-off. */
201 if (! output_is_line_wrapping (buffer)
202 || output_prefixing_rule (buffer) == DIAGNOSTICS_SHOW_PREFIX_ONCE
203 || output_prefixing_rule (buffer) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
204 line_wrap_cutoff (buffer) = output_line_cutoff (buffer);
205 else
206 {
207 int prefix_length =
208 output_prefix (buffer) ? strlen (output_prefix (buffer)) : 0;
209 /* If the prefix is ridiculously too long, output at least
210 32 characters. */
211 if (output_line_cutoff (buffer) - prefix_length < 32)
212 line_wrap_cutoff (buffer) = output_line_cutoff (buffer) + 32;
213 else
214 line_wrap_cutoff (buffer) = output_line_cutoff (buffer);
215 }
216 }
217
218 /* Sets the number of maximum characters per line BUFFER can output
219 in line-wrapping mode. A LENGTH value 0 suppresses line-wrapping. */
220
221 void
222 output_set_maximum_length (buffer, length)
223 output_buffer *buffer;
224 int length;
225 {
226 output_line_cutoff (buffer) = length;
227 set_real_maximum_length (buffer);
228 }
229
230 /* Sets BUFFER's PREFIX. */
231
232 void
233 output_set_prefix (buffer, prefix)
234 output_buffer *buffer;
235 const char *prefix;
236 {
237 output_prefix (buffer) = prefix;
238 set_real_maximum_length (buffer);
239 prefix_was_emitted_for (buffer) = 0;
240 output_indentation (buffer) = 0;
241 }
242
243 /* Return a pointer to the last character emitted in the output
244 BUFFER area. A NULL pointer means no character available. */
245 const char *
246 output_last_position (buffer)
247 const output_buffer *buffer;
248 {
249 const char *p = NULL;
250
251 if (obstack_base (&buffer->obstack) != obstack_next_free (&buffer->obstack))
252 p = ((const char *) obstack_next_free (&buffer->obstack)) - 1;
253 return p;
254 }
255
256 /* Free BUFFER's prefix, a previously malloc'd string. */
257
258 void
259 output_destroy_prefix (buffer)
260 output_buffer *buffer;
261 {
262 if (output_prefix (buffer) != NULL)
263 {
264 free ((char *) output_prefix (buffer));
265 output_prefix (buffer) = NULL;
266 }
267 }
268
269 /* Zero out any text output so far in BUFFER. */
270
271 void
272 output_clear_message_text (buffer)
273 output_buffer *buffer;
274 {
275 obstack_free (&buffer->obstack, obstack_base (&buffer->obstack));
276 output_text_length (buffer) = 0;
277 }
278
279 /* Zero out any formatting data used so far by BUFFER. */
280
281 static void
282 output_clear_data (buffer)
283 output_buffer *buffer;
284 {
285 output_buffer_text_cursor (buffer) = NULL;
286 output_buffer_ptr_to_format_args (buffer) = NULL;
287 prefix_was_emitted_for (buffer) = false;
288 output_indentation (buffer) = 0;
289 }
290
291 /* Construct an output BUFFER with PREFIX and of MAXIMUM_LENGTH
292 characters per line. */
293
294 void
295 init_output_buffer (buffer, prefix, maximum_length)
296 output_buffer *buffer;
297 const char *prefix;
298 int maximum_length;
299 {
300 memset (buffer, 0, sizeof (output_buffer));
301 obstack_init (&buffer->obstack);
302 output_buffer_attached_stream (buffer) = stderr;
303 output_line_cutoff (buffer) = maximum_length;
304 output_prefixing_rule (buffer) = diagnostic_prefixing_rule (global_dc);
305 output_set_prefix (buffer, prefix);
306 output_text_length (buffer) = 0;
307 output_clear_data (buffer);
308 }
309
310 /* Reinitialize BUFFER. */
311
312 void
313 output_clear (buffer)
314 output_buffer *buffer;
315 {
316 output_clear_message_text (buffer);
317 output_clear_data (buffer);
318 }
319
320 /* Finishes constructing a NULL-terminated character string representing
321 the BUFFERed message. */
322
323 const char *
324 output_finalize_message (buffer)
325 output_buffer *buffer;
326 {
327 obstack_1grow (&buffer->obstack, '\0');
328 return output_message_text (buffer);
329 }
330
331 void
332 flush_diagnostic_buffer ()
333 {
334 output_buffer_to_stream (diagnostic_buffer);
335 fflush (output_buffer_attached_stream (diagnostic_buffer));
336 }
337
338 /* Return the amount of characters BUFFER can accept to
339 make a full line. */
340
341 int
342 output_space_left (buffer)
343 const output_buffer *buffer;
344 {
345 return line_wrap_cutoff (buffer) - output_text_length (buffer);
346 }
347
348 /* Write out BUFFER's prefix. */
349
350 void
351 output_emit_prefix (buffer)
352 output_buffer *buffer;
353 {
354 if (output_prefix (buffer) != NULL)
355 {
356 switch (output_prefixing_rule (buffer))
357 {
358 default:
359 case DIAGNOSTICS_SHOW_PREFIX_NEVER:
360 break;
361
362 case DIAGNOSTICS_SHOW_PREFIX_ONCE:
363 if (prefix_was_emitted_for (buffer))
364 {
365 output_indent (buffer);
366 break;
367 }
368 output_indentation (buffer) += 3;
369 /* Fall through. */
370
371 case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
372 {
373 int prefix_length = strlen (output_prefix (buffer));
374 output_append_r (buffer, output_prefix (buffer), prefix_length);
375 prefix_was_emitted_for (buffer) = 1;
376 }
377 break;
378 }
379 }
380 }
381
382 /* Have BUFFER start a new line. */
383
384 void
385 output_add_newline (buffer)
386 output_buffer *buffer;
387 {
388 obstack_1grow (&buffer->obstack, '\n');
389 output_text_length (buffer) = 0;
390 }
391
392 /* Appends a character to BUFFER. */
393
394 void
395 output_add_character (buffer, c)
396 output_buffer *buffer;
397 int c;
398 {
399 if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
400 output_add_newline (buffer);
401 obstack_1grow (&buffer->obstack, c);
402 ++output_text_length (buffer);
403 }
404
405 /* Adds a space to BUFFER. */
406
407 void
408 output_add_space (buffer)
409 output_buffer *buffer;
410 {
411 if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
412 {
413 output_add_newline (buffer);
414 return;
415 }
416 obstack_1grow (&buffer->obstack, ' ');
417 ++output_text_length (buffer);
418 }
419
420 /* These functions format an INTEGER into BUFFER as suggested by their
421 names. */
422
423 void
424 output_decimal (buffer, i)
425 output_buffer *buffer;
426 int i;
427 {
428 output_formatted_integer (buffer, "%d", i);
429 }
430
431 static void
432 output_long_decimal (buffer, i)
433 output_buffer *buffer;
434 long int i;
435 {
436 output_formatted_integer (buffer, "%ld", i);
437 }
438
439 static void
440 output_unsigned_decimal (buffer, i)
441 output_buffer *buffer;
442 unsigned int i;
443 {
444 output_formatted_integer (buffer, "%u", i);
445 }
446
447 static void
448 output_long_unsigned_decimal (buffer, i)
449 output_buffer *buffer;
450 long unsigned int i;
451 {
452 output_formatted_integer (buffer, "%lu", i);
453 }
454
455 static void
456 output_octal (buffer, i)
457 output_buffer *buffer;
458 unsigned int i;
459 {
460 output_formatted_integer (buffer, "%o", i);
461 }
462
463 static void
464 output_long_octal (buffer, i)
465 output_buffer *buffer;
466 unsigned long int i;
467 {
468 output_formatted_integer (buffer, "%lo", i);
469 }
470
471 static void
472 output_hexadecimal (buffer, i)
473 output_buffer *buffer;
474 unsigned int i;
475 {
476 output_formatted_integer (buffer, "%x", i);
477 }
478
479 static void
480 output_long_hexadecimal (buffer, i)
481 output_buffer *buffer;
482 unsigned long int i;
483 {
484 output_formatted_integer (buffer, "%lx", i);
485 }
486
487 /* Append to BUFFER a string specified by its STARTING character
488 and LENGTH. */
489
490 static void
491 output_append_r (buffer, start, length)
492 output_buffer *buffer;
493 const char *start;
494 int length;
495 {
496 obstack_grow (&buffer->obstack, start, length);
497 output_text_length (buffer) += length;
498 }
499
500 /* Append a string deliminated by START and END to BUFFER. No wrapping is
501 done. However, if beginning a new line then emit output_prefix (BUFFER)
502 and skip any leading whitespace if appropriate. The caller must ensure
503 that it is safe to do so. */
504
505 void
506 output_append (buffer, start, end)
507 output_buffer *buffer;
508 const char *start;
509 const char *end;
510 {
511 /* Emit prefix and skip whitespace if we're starting a new line. */
512 if (is_starting_newline (buffer))
513 {
514 output_emit_prefix (buffer);
515 if (output_is_line_wrapping (buffer))
516 while (start != end && *start == ' ')
517 ++start;
518 }
519 output_append_r (buffer, start, end - start);
520 }
521
522 static void
523 output_indent (buffer)
524 output_buffer *buffer;
525 {
526 int n = output_indentation (buffer);
527 int i;
528
529 for (i = 0; i < n; ++i)
530 output_add_character (buffer, ' ');
531 }
532
533 /* Wrap a text delimited by START and END into BUFFER. */
534
535 static void
536 wrap_text (buffer, start, end)
537 output_buffer *buffer;
538 const char *start;
539 const char *end;
540 {
541 int is_wrapping = output_is_line_wrapping (buffer);
542
543 while (start != end)
544 {
545 /* Dump anything bordered by whitespaces. */
546 {
547 const char *p = start;
548 while (p != end && *p != ' ' && *p != '\n')
549 ++p;
550 if (is_wrapping && p - start >= output_space_left (buffer))
551 output_add_newline (buffer);
552 output_append (buffer, start, p);
553 start = p;
554 }
555
556 if (start != end && *start == ' ')
557 {
558 output_add_space (buffer);
559 ++start;
560 }
561 if (start != end && *start == '\n')
562 {
563 output_add_newline (buffer);
564 ++start;
565 }
566 }
567 }
568
569 /* Same as wrap_text but wrap text only when in line-wrapping mode. */
570
571 static void
572 maybe_wrap_text (buffer, start, end)
573 output_buffer *buffer;
574 const char *start;
575 const char *end;
576 {
577 if (output_is_line_wrapping (buffer))
578 wrap_text (buffer, start, end);
579 else
580 output_append (buffer, start, end);
581 }
582
583
584 /* Append a STRING to BUFFER; the STRING might be line-wrapped if in
585 appropriate mode. */
586
587 void
588 output_add_string (buffer, str)
589 output_buffer *buffer;
590 const char *str;
591 {
592 maybe_wrap_text (buffer, str, str + (str ? strlen (str) : 0));
593 }
594
595 /* Flush the content of BUFFER onto the attached stream,
596 and reinitialize. */
597
598 static void
599 output_buffer_to_stream (buffer)
600 output_buffer *buffer;
601 {
602 const char *text = output_finalize_message (buffer);
603 fputs (text, output_buffer_attached_stream (buffer));
604 output_clear_message_text (buffer);
605 }
606
607 /* Format a message pointed to by output_buffer_text_cursor (BUFFER) using
608 output_buffer_format_args (BUFFER) as appropriate. The following format
609 specifiers are recognized as being language independent:
610 %d, %i: (signed) integer in base ten.
611 %u: unsigned integer in base ten.
612 %o: unsigned integer in base eight.
613 %x: unsigned integer in base sixteen.
614 %ld, %li, %lo, %lu, %lx: long versions of the above.
615 %c: character.
616 %s: string.
617 %%: `%'.
618 %*.s: a substring the length of which is specified by an integer. */
619
620 static void
621 output_format (buffer)
622 output_buffer *buffer;
623 {
624 for (; *output_buffer_text_cursor (buffer);
625 ++output_buffer_text_cursor (buffer))
626 {
627 int long_integer = 0;
628
629 /* Ignore text. */
630 {
631 const char *p = output_buffer_text_cursor (buffer);
632 while (*p && *p != '%')
633 ++p;
634 wrap_text (buffer, output_buffer_text_cursor (buffer), p);
635 output_buffer_text_cursor (buffer) = p;
636 }
637
638 if (!*output_buffer_text_cursor (buffer))
639 break;
640
641 /* We got a '%'. Let's see what happens. Record whether we're
642 parsing a long integer format specifier. */
643 if (*++output_buffer_text_cursor (buffer) == 'l')
644 {
645 long_integer = 1;
646 ++output_buffer_text_cursor (buffer);
647 }
648
649 /* Handle %c, %d, %i, %ld, %li, %lo, %lu, %lx, %o, %s, %u,
650 %x, %.*s; %%. And nothing else. Front-ends should install
651 printers to grok language specific format specifiers. */
652 switch (*output_buffer_text_cursor (buffer))
653 {
654 case 'c':
655 output_add_character
656 (buffer, va_arg (output_buffer_format_args (buffer), int));
657 break;
658
659 case 'd':
660 case 'i':
661 if (long_integer)
662 output_long_decimal
663 (buffer, va_arg (output_buffer_format_args (buffer), long int));
664 else
665 output_decimal
666 (buffer, va_arg (output_buffer_format_args (buffer), int));
667 break;
668
669 case 'o':
670 if (long_integer)
671 output_long_octal (buffer,
672 va_arg (output_buffer_format_args (buffer),
673 unsigned long int));
674 else
675 output_octal (buffer,
676 va_arg (output_buffer_format_args (buffer),
677 unsigned int));
678 break;
679
680 case 's':
681 output_add_string (buffer,
682 va_arg (output_buffer_format_args (buffer),
683 const char *));
684 break;
685
686 case 'u':
687 if (long_integer)
688 output_long_unsigned_decimal
689 (buffer, va_arg (output_buffer_format_args (buffer),
690 long unsigned int));
691 else
692 output_unsigned_decimal
693 (buffer, va_arg (output_buffer_format_args (buffer),
694 unsigned int));
695 break;
696
697 case 'x':
698 if (long_integer)
699 output_long_hexadecimal
700 (buffer, va_arg (output_buffer_format_args (buffer),
701 unsigned long int));
702 else
703 output_hexadecimal
704 (buffer, va_arg (output_buffer_format_args (buffer),
705 unsigned int));
706 break;
707
708 case '%':
709 output_add_character (buffer, '%');
710 break;
711
712 case '.':
713 {
714 int n;
715 const char *s;
716 /* We handle no precision specifier but `%.*s'. */
717 if (*++output_buffer_text_cursor (buffer) != '*')
718 abort ();
719 else if (*++output_buffer_text_cursor (buffer) != 's')
720 abort ();
721 n = va_arg (output_buffer_format_args (buffer), int);
722 s = va_arg (output_buffer_format_args (buffer), const char *);
723 output_append (buffer, s, s + n);
724 }
725 break;
726
727 default:
728 if (!buffer->format_decoder || !(*buffer->format_decoder) (buffer))
729 {
730 /* Hmmm. The front-end failed to install a format translator
731 but called us with an unrecognized format. Sorry. */
732 abort ();
733 }
734 }
735 }
736 }
737
738 static char *
739 vbuild_message_string (msg, ap)
740 const char *msg;
741 va_list ap;
742 {
743 char *str;
744
745 vasprintf (&str, msg, ap);
746 return str;
747 }
748
749 /* Return a malloc'd string containing MSG formatted a la
750 printf. The caller is responsible for freeing the memory. */
751
752 static char *
753 build_message_string VPARAMS ((const char *msg, ...))
754 {
755 char *str;
756
757 VA_OPEN (ap, msg);
758 VA_FIXEDARG (ap, const char *, msg);
759
760 str = vbuild_message_string (msg, ap);
761
762 VA_CLOSE (ap);
763
764 return str;
765 }
766
767 /* Return a malloc'd string describing a location. The caller is
768 responsible for freeing the memory. */
769
770 char *
771 context_as_prefix (file, line, warn)
772 const char *file;
773 int line;
774 int warn;
775 {
776 if (file)
777 {
778 if (warn)
779 return build_message_string (_("%s:%d: warning: "), file, line);
780 else
781 return build_message_string ("%s:%d: ", file, line);
782 }
783 else
784 {
785 if (warn)
786 return build_message_string (_("%s: warning: "), progname);
787 else
788 return build_message_string ("%s: ", progname);
789 }
790 }
791
792 /* Same as context_as_prefix, but only the source FILE is given. */
793
794 char *
795 file_name_as_prefix (f)
796 const char *f;
797 {
798 return build_message_string ("%s: ", f);
799 }
800
801 /* Format a MESSAGE into BUFFER. Automatically wrap lines. */
802
803 static void
804 output_do_printf (buffer, msg)
805 output_buffer *buffer;
806 const char *msg;
807 {
808 char *message = vbuild_message_string (msg,
809 output_buffer_format_args (buffer));
810
811 wrap_text (buffer, message, message + strlen (message));
812 free (message);
813 }
814
815
816 /* Format a message into BUFFER a la printf. */
817
818 void
819 output_printf VPARAMS ((struct output_buffer *buffer, const char *msgid, ...))
820 {
821 va_list *old_args;
822
823 VA_OPEN (ap, msgid);
824 VA_FIXEDARG (ap, output_buffer *, buffer);
825 VA_FIXEDARG (ap, const char *, msgid);
826
827 old_args = output_buffer_ptr_to_format_args (buffer);
828 output_buffer_ptr_to_format_args (buffer) = &ap;
829 output_do_printf (buffer, _(msgid));
830 output_buffer_ptr_to_format_args (buffer) = old_args;
831 VA_CLOSE (ap);
832 }
833
834 /* Print a message relevant to the given DECL. */
835
836 static void
837 format_with_decl (buffer, decl)
838 output_buffer *buffer;
839 tree decl;
840 {
841 const char *p;
842
843 /* Do magic to get around lack of varargs support for insertion
844 of arguments into existing list. We know that the decl is first;
845 we ass_u_me that it will be printed with "%s". */
846 for (p = output_buffer_text_cursor (buffer); *p; ++p)
847 {
848 if (*p == '%')
849 {
850 if (*(p + 1) == '%')
851 ++p;
852 else if (*(p + 1) != 's')
853 abort ();
854 else
855 break;
856 }
857 }
858
859 /* Print the left-hand substring. */
860 maybe_wrap_text (buffer, output_buffer_text_cursor (buffer), p);
861
862 if (*p == '%') /* Print the name. */
863 {
864 const char *const n = (DECL_NAME (decl)
865 ? (*lang_hooks.decl_printable_name) (decl, 2)
866 : _("((anonymous))"));
867 output_add_string (buffer, n);
868 while (*p)
869 {
870 ++p;
871 if (ISALPHA (*(p - 1) & 0xFF))
872 break;
873 }
874 }
875
876 if (*p) /* Print the rest of the message. */
877 {
878 output_buffer_text_cursor (buffer) = p;
879 output_format (buffer);
880 }
881 }
882
883
884 /* Report a diagnostic MESSAGE at the declaration DECL.
885 MSG is a format string which uses %s to substitute the declaration
886 name; subsequent substitutions are a la output_format. */
887
888 static void
889 diagnostic_for_decl (decl, msgid, args_ptr, warn)
890 tree decl;
891 const char *msgid;
892 va_list *args_ptr;
893 int warn;
894 {
895 output_state os;
896
897 if (diagnostic_lock++)
898 error_recursion ();
899
900 if (count_error (warn))
901 {
902 os = output_buffer_state (diagnostic_buffer);
903 report_error_function (DECL_SOURCE_FILE (decl));
904 output_set_prefix
905 (diagnostic_buffer, context_as_prefix
906 (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl), warn));
907 output_buffer_ptr_to_format_args (diagnostic_buffer) = args_ptr;
908 output_buffer_text_cursor (diagnostic_buffer) = _(msgid);
909 format_with_decl (diagnostic_buffer, decl);
910 output_flush (&global_dc->buffer);
911 output_destroy_prefix (diagnostic_buffer);
912
913 output_buffer_state (diagnostic_buffer) = os;
914 }
915 diagnostic_lock--;
916 }
917
918 /* Flush the content of BUFFER onto the attached stream. */
919
920 static void
921 output_flush (buffer)
922 output_buffer *buffer;
923 {
924 output_buffer_to_stream (buffer);
925 output_clear_data (buffer);
926 fputc ('\n', output_buffer_attached_stream (buffer));
927 fflush (output_buffer_attached_stream (buffer));
928 }
929
930 /* Helper subroutine of output_verbatim and verbatim. Do the appropriate
931 settings needed by BUFFER for a verbatim formatting. */
932
933 static void
934 output_do_verbatim (buffer, msgid, args_ptr)
935 output_buffer *buffer;
936 const char *msgid;
937 va_list *args_ptr;
938 {
939 output_state os;
940
941 os = output_buffer_state (buffer);
942 output_prefix (buffer) = NULL;
943 output_prefixing_rule (buffer) = DIAGNOSTICS_SHOW_PREFIX_NEVER;
944 output_buffer_text_cursor (buffer) = _(msgid);
945 output_buffer_ptr_to_format_args (buffer) = args_ptr;
946 output_set_maximum_length (buffer, 0);
947 output_format (buffer);
948 output_buffer_state (buffer) = os;
949 }
950
951 /* Output MESSAGE verbatim into BUFFER. */
952
953 void
954 output_verbatim VPARAMS ((output_buffer *buffer, const char *msgid, ...))
955 {
956 VA_OPEN (ap, msgid);
957 VA_FIXEDARG (ap, output_buffer *, buffer);
958 VA_FIXEDARG (ap, const char *, msgid);
959
960 output_do_verbatim (buffer, msgid, &ap);
961 VA_CLOSE (ap);
962 }
963 \f
964 /* Count an error or warning. Return 1 if the message should be printed. */
965
966 int
967 count_error (warningp)
968 int warningp;
969 {
970 if (warningp && !diagnostic_report_warnings_p ())
971 return 0;
972
973 if (warningp && !warnings_are_errors)
974 warningcount++;
975 else
976 {
977 static int warning_message = 0;
978
979 if (warningp && !warning_message)
980 {
981 verbatim ("%s: warnings being treated as errors\n", progname);
982 warning_message = 1;
983 }
984 errorcount++;
985 }
986
987 return 1;
988 }
989
990 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it
991 runs its second argument through gettext. */
992
993 void
994 fnotice VPARAMS ((FILE *file, const char *msgid, ...))
995 {
996 VA_OPEN (ap, msgid);
997 VA_FIXEDARG (ap, FILE *, file);
998 VA_FIXEDARG (ap, const char *, msgid);
999
1000 vfprintf (file, _(msgid), ap);
1001 VA_CLOSE (ap);
1002 }
1003
1004
1005 /* Print a fatal I/O error message. Argument are like printf.
1006 Also include a system error message based on `errno'. */
1007
1008 void
1009 fatal_io_error VPARAMS ((const char *msgid, ...))
1010 {
1011 output_state os;
1012
1013 VA_OPEN (ap, msgid);
1014 VA_FIXEDARG (ap, const char *, msgid);
1015
1016 os = output_buffer_state (diagnostic_buffer);
1017
1018 output_printf (diagnostic_buffer, "%s: %s: ", progname, xstrerror (errno));
1019 output_buffer_ptr_to_format_args (diagnostic_buffer) = &ap;
1020 output_buffer_text_cursor (diagnostic_buffer) = _(msgid);
1021 output_format (diagnostic_buffer);
1022 output_flush (&global_dc->buffer);
1023 output_buffer_state (diagnostic_buffer) = os;
1024 VA_CLOSE (ap);
1025 exit (FATAL_EXIT_CODE);
1026 }
1027
1028 /* Issue a pedantic warning MSGID. */
1029
1030 void
1031 pedwarn VPARAMS ((const char *msgid, ...))
1032 {
1033 diagnostic_context dc;
1034
1035 VA_OPEN (ap, msgid);
1036 VA_FIXEDARG (ap, const char *, msgid);
1037
1038 set_diagnostic_context
1039 (&dc, msgid, &ap, input_filename, lineno, !flag_pedantic_errors);
1040 report_diagnostic (&dc);
1041 VA_CLOSE (ap);
1042 }
1043
1044 /* Issue a pedantic warning about DECL. */
1045
1046 void
1047 pedwarn_with_decl VPARAMS ((tree decl, const char *msgid, ...))
1048 {
1049 VA_OPEN (ap, msgid);
1050 VA_FIXEDARG (ap, tree, decl);
1051 VA_FIXEDARG (ap, const char *, msgid);
1052
1053 /* We don't want -pedantic-errors to cause the compilation to fail from
1054 "errors" in system header files. Sometimes fixincludes can't fix what's
1055 broken (eg: unsigned char bitfields - fixing it may change the alignment
1056 which will cause programs to mysteriously fail because the C library
1057 or kernel uses the original layout). There's no point in issuing a
1058 warning either, it's just unnecessary noise. */
1059 if (!DECL_IN_SYSTEM_HEADER (decl))
1060 diagnostic_for_decl (decl, msgid, &ap, !flag_pedantic_errors);
1061 VA_CLOSE (ap);
1062 }
1063
1064 /* Same as above but within the context FILE and LINE. */
1065
1066 void
1067 pedwarn_with_file_and_line VPARAMS ((const char *file, int line,
1068 const char *msgid, ...))
1069 {
1070 diagnostic_context dc;
1071
1072 VA_OPEN (ap, msgid);
1073 VA_FIXEDARG (ap, const char *, file);
1074 VA_FIXEDARG (ap, int, line);
1075 VA_FIXEDARG (ap, const char *, msgid);
1076
1077 set_diagnostic_context (&dc, msgid, &ap, file, line, !flag_pedantic_errors);
1078 report_diagnostic (&dc);
1079 VA_CLOSE (ap);
1080 }
1081
1082 /* Just apologize with MSGID. */
1083
1084 void
1085 sorry VPARAMS ((const char *msgid, ...))
1086 {
1087 output_state os;
1088
1089 VA_OPEN (ap, msgid);
1090 VA_FIXEDARG (ap, const char *, msgid);
1091
1092 ++sorrycount;
1093 os = output_buffer_state (diagnostic_buffer);
1094
1095 output_set_prefix
1096 (diagnostic_buffer, context_as_prefix (input_filename, lineno, 0));
1097 output_printf (diagnostic_buffer, "sorry, not implemented: ");
1098 output_buffer_ptr_to_format_args (diagnostic_buffer) = &ap;
1099 output_buffer_text_cursor (diagnostic_buffer) = _(msgid);
1100 output_format (diagnostic_buffer);
1101 output_flush (&global_dc->buffer);
1102 output_buffer_state (diagnostic_buffer) = os;
1103 VA_CLOSE (ap);
1104 }
1105
1106 /* Called when the start of a function definition is parsed,
1107 this function prints on stderr the name of the function. */
1108
1109 void
1110 announce_function (decl)
1111 tree decl;
1112 {
1113 if (! quiet_flag)
1114 {
1115 if (rtl_dump_and_exit)
1116 verbatim ("%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
1117 else
1118 verbatim (" %s", (*lang_hooks.decl_printable_name) (decl, 2));
1119 fflush (stderr);
1120 output_needs_newline (diagnostic_buffer) = 1;
1121 record_last_error_function ();
1122 }
1123 }
1124
1125 /* The default function to print out name of current function that caused
1126 an error. */
1127
1128 void
1129 lhd_print_error_function (context, file)
1130 diagnostic_context *context;
1131 const char *file;
1132 {
1133 if (error_function_changed ())
1134 {
1135 char *prefix = file ? build_message_string ("%s: ", file) : NULL;
1136 output_state os;
1137
1138 os = diagnostic_state (context);
1139 output_set_prefix ((output_buffer *) context, prefix);
1140
1141 if (current_function_decl == NULL)
1142 output_add_string ((output_buffer *) context, _("At top level:"));
1143 else
1144 {
1145 if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
1146 output_printf
1147 ((output_buffer *) context, "In member function `%s':",
1148 (*lang_hooks.decl_printable_name) (current_function_decl, 2));
1149 else
1150 output_printf
1151 ((output_buffer *) context, "In function `%s':",
1152 (*lang_hooks.decl_printable_name) (current_function_decl, 2));
1153 }
1154 output_add_newline ((output_buffer *) context);
1155
1156 record_last_error_function ();
1157 output_buffer_to_stream ((output_buffer *) context);
1158 diagnostic_state (context) = os;
1159 free ((char*) prefix);
1160 }
1161 }
1162
1163 /* Prints out, if necessary, the name of the current function
1164 that caused an error. Called from all error and warning functions.
1165 We ignore the FILE parameter, as it cannot be relied upon. */
1166
1167 void
1168 report_error_function (file)
1169 const char *file ATTRIBUTE_UNUSED;
1170 {
1171 report_problematic_module ((output_buffer *) global_dc);
1172 (*lang_hooks.print_error_function) (global_dc, input_filename);
1173 }
1174
1175 void
1176 error_with_file_and_line VPARAMS ((const char *file, int line,
1177 const char *msgid, ...))
1178 {
1179 diagnostic_context dc;
1180
1181 VA_OPEN (ap, msgid);
1182 VA_FIXEDARG (ap, const char *, file);
1183 VA_FIXEDARG (ap, int, line);
1184 VA_FIXEDARG (ap, const char *, msgid);
1185
1186 set_diagnostic_context (&dc, msgid, &ap, file, line, /* warn = */ 0);
1187 report_diagnostic (&dc);
1188 VA_CLOSE (ap);
1189 }
1190
1191 void
1192 error_with_decl VPARAMS ((tree decl, const char *msgid, ...))
1193 {
1194 VA_OPEN (ap, msgid);
1195 VA_FIXEDARG (ap, tree, decl);
1196 VA_FIXEDARG (ap, const char *, msgid);
1197
1198 diagnostic_for_decl (decl, msgid, &ap, /* warn = */ 0);
1199 VA_CLOSE (ap);
1200 }
1201
1202
1203 /* Report an error message. The arguments are like that of printf. */
1204
1205 void
1206 error VPARAMS ((const char *msgid, ...))
1207 {
1208 diagnostic_context dc;
1209
1210 VA_OPEN (ap, msgid);
1211 VA_FIXEDARG (ap, const char *, msgid);
1212
1213 set_diagnostic_context
1214 (&dc, msgid, &ap, input_filename, lineno, /* warn = */ 0);
1215 report_diagnostic (&dc);
1216 VA_CLOSE (ap);
1217 }
1218
1219 /* Likewise, except that the compilation is terminated after printing the
1220 error message. */
1221
1222 void
1223 fatal_error VPARAMS ((const char *msgid, ...))
1224 {
1225 diagnostic_context dc;
1226
1227 VA_OPEN (ap, msgid);
1228 VA_FIXEDARG (ap, const char *, msgid);
1229
1230 set_diagnostic_context
1231 (&dc, msgid, &ap, input_filename, lineno, /* warn = */ 0);
1232 report_diagnostic (&dc);
1233 VA_CLOSE (ap);
1234
1235 fnotice (stderr, "compilation terminated.\n");
1236 exit (FATAL_EXIT_CODE);
1237 }
1238
1239 /* Report a compiler error at the current line number. Allow a front end to
1240 intercept the message. */
1241
1242 static void (*internal_error_function) PARAMS ((const char *, va_list *));
1243
1244 /* Set the function to call when a compiler error occurs. */
1245
1246 void
1247 set_internal_error_function (f)
1248 void (*f) PARAMS ((const char *, va_list *));
1249 {
1250 internal_error_function = f;
1251 }
1252
1253 void
1254 internal_error VPARAMS ((const char *msgid, ...))
1255 {
1256 diagnostic_context dc;
1257
1258 VA_OPEN (ap, msgid);
1259 VA_FIXEDARG (ap, const char *, msgid);
1260
1261 if (diagnostic_lock)
1262 error_recursion ();
1263
1264 #ifndef ENABLE_CHECKING
1265 if (errorcount > 0 || sorrycount > 0)
1266 {
1267 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
1268 input_filename, lineno);
1269 exit (FATAL_EXIT_CODE);
1270 }
1271 #endif
1272
1273 if (internal_error_function != 0)
1274 (*internal_error_function) (_(msgid), &ap);
1275
1276 set_diagnostic_context
1277 (&dc, msgid, &ap, input_filename, lineno, /* warn = */0);
1278 report_diagnostic (&dc);
1279 VA_CLOSE (ap);
1280
1281 fnotice (stderr,
1282 "Please submit a full bug report,\n\
1283 with preprocessed source if appropriate.\n\
1284 See %s for instructions.\n", GCCBUGURL);
1285 exit (FATAL_EXIT_CODE);
1286 }
1287
1288 void
1289 warning_with_file_and_line VPARAMS ((const char *file, int line,
1290 const char *msgid, ...))
1291 {
1292 diagnostic_context dc;
1293
1294 VA_OPEN (ap, msgid);
1295 VA_FIXEDARG (ap, const char *, file);
1296 VA_FIXEDARG (ap, int, line);
1297 VA_FIXEDARG (ap, const char *, msgid);
1298
1299 set_diagnostic_context (&dc, msgid, &ap, file, line, /* warn = */ 1);
1300 report_diagnostic (&dc);
1301 VA_CLOSE (ap);
1302 }
1303
1304 void
1305 warning_with_decl VPARAMS ((tree decl, const char *msgid, ...))
1306 {
1307 VA_OPEN (ap, msgid);
1308 VA_FIXEDARG (ap, tree, decl);
1309 VA_FIXEDARG (ap, const char *, msgid);
1310
1311 diagnostic_for_decl (decl, msgid, &ap, /* warn = */ 1);
1312 VA_CLOSE (ap);
1313 }
1314
1315 void
1316 warning VPARAMS ((const char *msgid, ...))
1317 {
1318 diagnostic_context dc;
1319
1320 VA_OPEN (ap, msgid);
1321 VA_FIXEDARG (ap, const char *, msgid);
1322
1323 set_diagnostic_context
1324 (&dc, msgid, &ap, input_filename, lineno, /* warn = */ 1);
1325 report_diagnostic (&dc);
1326 VA_CLOSE (ap);
1327 }
1328
1329
1330 /* Same as above but use diagnostic_buffer. */
1331
1332 void
1333 verbatim VPARAMS ((const char *msgid, ...))
1334 {
1335 VA_OPEN (ap, msgid);
1336 VA_FIXEDARG (ap, const char *, msgid);
1337
1338 output_do_verbatim (diagnostic_buffer, msgid, &ap);
1339 output_buffer_to_stream (diagnostic_buffer);
1340 VA_CLOSE (ap);
1341 }
1342
1343 /* Report a diagnostic message (an error or a warning) as specified by
1344 DC. This function is *the* subroutine in terms of which front-ends
1345 should implement their specific diagnostic handling modules. The
1346 front-end independent format specifiers are exactly those described
1347 in the documentation of output_format. */
1348
1349 void
1350 report_diagnostic (dc)
1351 diagnostic_context *dc;
1352 {
1353 output_state os;
1354
1355 if (diagnostic_lock++)
1356 error_recursion ();
1357
1358 if (count_error (diagnostic_is_warning (dc)))
1359 {
1360 os = output_buffer_state (diagnostic_buffer);
1361 diagnostic_msg = diagnostic_message (dc);
1362 diagnostic_args = diagnostic_argument_list (dc);
1363 (*diagnostic_starter (dc)) (diagnostic_buffer, dc);
1364 output_format (diagnostic_buffer);
1365 (*diagnostic_finalizer (dc)) (diagnostic_buffer, dc);
1366 output_flush (&global_dc->buffer);
1367 output_buffer_state (diagnostic_buffer) = os;
1368 }
1369
1370 diagnostic_lock--;
1371 }
1372
1373 /* Inform the user that an error occurred while trying to report some
1374 other error. This indicates catastrophic internal inconsistencies,
1375 so give up now. But do try to flush out the previous error.
1376 This mustn't use internal_error, that will cause infinite recursion. */
1377
1378 static void
1379 error_recursion ()
1380 {
1381 if (diagnostic_lock < 3)
1382 output_flush (&global_dc->buffer);
1383
1384 fnotice (stderr,
1385 "Internal compiler error: Error reporting routines re-entered.\n");
1386 fnotice (stderr,
1387 "Please submit a full bug report,\n\
1388 with preprocessed source if appropriate.\n\
1389 See %s for instructions.\n", GCCBUGURL);
1390 exit (FATAL_EXIT_CODE);
1391 }
1392
1393 /* Given a partial pathname as input, return another pathname that
1394 shares no directory elements with the pathname of __FILE__. This
1395 is used by fancy_abort() to print `Internal compiler error in expr.c'
1396 instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */
1397
1398 const char *
1399 trim_filename (name)
1400 const char *name;
1401 {
1402 static const char this_file[] = __FILE__;
1403 const char *p = name, *q = this_file;
1404
1405 /* First skip any "../" in each filename. This allows us to give a proper
1406 reference to a file in a subdirectory. */
1407 while (p[0] == '.' && p[1] == '.'
1408 && (p[2] == DIR_SEPARATOR
1409 #ifdef DIR_SEPARATOR_2
1410 || p[2] == DIR_SEPARATOR_2
1411 #endif
1412 ))
1413 p += 3;
1414
1415 while (q[0] == '.' && q[1] == '.'
1416 && (q[2] == DIR_SEPARATOR
1417 #ifdef DIR_SEPARATOR_2
1418 || p[2] == DIR_SEPARATOR_2
1419 #endif
1420 ))
1421 q += 3;
1422
1423 /* Now skip any parts the two filenames have in common. */
1424 while (*p == *q && *p != 0 && *q != 0)
1425 p++, q++;
1426
1427 /* Now go backwards until the previous directory separator. */
1428 while (p > name && p[-1] != DIR_SEPARATOR
1429 #ifdef DIR_SEPARATOR_2
1430 && p[-1] != DIR_SEPARATOR_2
1431 #endif
1432 )
1433 p--;
1434
1435 return p;
1436 }
1437
1438 /* Report an internal compiler error in a friendly manner and without
1439 dumping core. */
1440
1441 void
1442 fancy_abort (file, line, function)
1443 const char *file;
1444 int line;
1445 const char *function;
1446 {
1447 internal_error ("Internal compiler error in %s, at %s:%d",
1448 function, trim_filename (file), line);
1449 }
1450
1451 /* Setup DC for reporting a diagnostic MESSAGE (an error or a WARNING),
1452 using arguments pointed to by ARGS_PTR, issued at a location specified
1453 by FILE and LINE. */
1454
1455 void
1456 set_diagnostic_context (dc, msgid, args_ptr, file, line, warn)
1457 diagnostic_context *dc;
1458 const char *msgid;
1459 va_list *args_ptr;
1460 const char *file;
1461 int line;
1462 int warn;
1463 {
1464 memset (dc, 0, sizeof (diagnostic_context));
1465 diagnostic_message (dc) = _(msgid);
1466 diagnostic_argument_list (dc) = args_ptr;
1467 diagnostic_file_location (dc) = file;
1468 diagnostic_line_location (dc) = line;
1469 diagnostic_is_warning (dc) = warn;
1470 diagnostic_starter (dc) = diagnostic_starter (global_dc);
1471 diagnostic_finalizer (dc) = diagnostic_finalizer (global_dc);
1472 }
1473
1474 void
1475 report_problematic_module (buffer)
1476 output_buffer *buffer;
1477 {
1478 struct file_stack *p;
1479
1480 if (output_needs_newline (buffer))
1481 {
1482 output_add_newline (buffer);
1483 output_needs_newline (buffer) = 0;
1484 }
1485
1486 if (input_file_stack && input_file_stack->next != 0
1487 && error_module_changed ())
1488 {
1489 for (p = input_file_stack->next; p; p = p->next)
1490 if (p == input_file_stack->next)
1491 output_verbatim
1492 (buffer, "In file included from %s:%d", p->name, p->line);
1493 else
1494 output_verbatim
1495 (buffer, ",\n from %s:%d", p->name, p->line);
1496 output_verbatim (buffer, ":\n");
1497 record_last_error_module ();
1498 }
1499 }
1500
1501 static void
1502 default_diagnostic_starter (buffer, dc)
1503 output_buffer *buffer;
1504 diagnostic_context *dc;
1505 {
1506 report_error_function (diagnostic_file_location (dc));
1507 output_set_prefix (buffer,
1508 context_as_prefix (diagnostic_file_location (dc),
1509 diagnostic_line_location (dc),
1510 diagnostic_is_warning (dc)));
1511 }
1512
1513 static void
1514 default_diagnostic_finalizer (buffer, dc)
1515 output_buffer *buffer;
1516 diagnostic_context *dc __attribute__((__unused__));
1517 {
1518 output_destroy_prefix (buffer);
1519 }
1520
1521 void
1522 warn_deprecated_use (node)
1523 tree node;
1524 {
1525 if (node == 0 || !warn_deprecated_decl)
1526 return;
1527
1528 if (DECL_P (node))
1529 warning ("`%s' is deprecated (declared at %s:%d)",
1530 IDENTIFIER_POINTER (DECL_NAME (node)),
1531 DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
1532 else if (TYPE_P (node))
1533 {
1534 const char *what = NULL;
1535 tree decl = TYPE_STUB_DECL (node);
1536
1537 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
1538 what = IDENTIFIER_POINTER (TYPE_NAME (node));
1539 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
1540 && DECL_NAME (TYPE_NAME (node)))
1541 what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node)));
1542
1543 if (what)
1544 {
1545 if (decl)
1546 warning ("`%s' is deprecated (declared at %s:%d)", what,
1547 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1548 else
1549 warning ("`%s' is deprecated", what);
1550 }
1551 else if (decl)
1552 warning ("type is deprecated (declared at %s:%d)",
1553 DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
1554 else
1555 warning ("type is deprecated");
1556 }
1557 }
This page took 0.114094 seconds and 5 git commands to generate.