]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/f/bad.c
re PR fortran/13930 (derived type with intent(in) attribute not accepted)
[thirdparty/gcc.git] / gcc / f / bad.c
CommitLineData
5ff904cd 1/* bad.c -- Implementation File (module.c template V1.0)
77f9b92c 2 Copyright (C) 1995, 2002, 2003 Free Software Foundation, Inc.
25d7717e 3 Contributed by James Craig Burley.
5ff904cd
JL
4
5This file is part of GNU Fortran.
6
7GNU Fortran is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU Fortran is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Fortran; see the file COPYING. If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA.
21
22 Related Modules:
23 None
24
25 Description:
26 Handles the displaying of diagnostic messages regarding the user's source
27 files.
28
29 Modifications:
30*/
31
32/* If there's a %E or %4 in the messages, set this to at least 5,
33 for example. */
34
35#define FFEBAD_MAX_ 6
36
37/* Include files. */
38
39#include "proj.h"
5ff904cd 40#include "bad.h"
15a40ced 41#include "flags.h"
5ff904cd 42#include "com.h"
15a40ced 43#include "toplev.h"
5ff904cd 44#include "where.h"
f1685b7c 45#include "intl.h"
47b69537 46#include "diagnostic.h"
5ff904cd
JL
47
48/* Externals defined here. */
49
50bool ffebad_is_inhibited_ = FALSE;
51
52/* Simple definitions and enumerations. */
53
54#define FFEBAD_LONG_MSGS_ 1 /* 0 to use short (or same) messages. */
55
56/* Internal typedefs. */
57
58
59/* Private include files. */
60
61
62/* Internal structure definitions. */
63
64struct _ffebad_message_
65 {
8b60264b
KG
66 const ffebadSeverity severity;
67 const char *const message;
5ff904cd
JL
68 };
69
70/* Static objects accessed by functions in this module. */
71
8b60264b 72static const struct _ffebad_message_ ffebad_messages_[]
5ff904cd
JL
73=
74{
f1685b7c 75#define FFEBAD_MSG(kwd,sev,msgid) { sev, msgid },
5ff904cd 76#if FFEBAD_LONG_MSGS_ == 0
f1685b7c
ZW
77#define LONG(m)
78#define SHORT(m) m
5ff904cd 79#else
f1685b7c
ZW
80#define LONG(m) m
81#define SHORT(m)
5ff904cd
JL
82#endif
83#include "bad.def"
f1685b7c
ZW
84#undef FFEBAD_MSG
85#undef LONG
86#undef SHORT
5ff904cd
JL
87};
88
89static struct
90 {
91 ffewhereLine line;
92 ffewhereColumn col;
93 ffebadIndex tag;
94 }
95
96ffebad_here_[FFEBAD_MAX_];
26f096f9 97static const char *ffebad_string_[FFEBAD_MAX_];
5ff904cd
JL
98static ffebadIndex ffebad_order_[FFEBAD_MAX_];
99static ffebad ffebad_errnum_;
100static ffebadSeverity ffebad_severity_;
26f096f9 101static const char *ffebad_message_;
5ff904cd
JL
102static unsigned char ffebad_index_;
103static ffebadIndex ffebad_places_;
104static bool ffebad_is_temp_inhibited_; /* Effective setting of
105 _is_inhibited_ for this
106 _start/_finish invocation. */
107
108/* Static functions (internal). */
109
26f096f9 110static int ffebad_bufputs_ (char buf[], int bufi, const char *s);
5ff904cd
JL
111
112/* Internal macros. */
113
114#define ffebad_bufflush_(buf, bufi) \
115 (((buf)[bufi] = '\0'), fputs ((buf), stderr), 0)
116#define ffebad_bufputc_(buf, bufi, c) \
117 (((bufi) == ARRAY_SIZE (buf)) \
118 ? (ffebad_bufflush_ ((buf), (bufi)), ((buf)[0] = (c)), 1) \
119 : (((buf)[bufi] = (c)), (bufi) + 1))
120\f
121
122static int
26f096f9 123ffebad_bufputs_ (char buf[], int bufi, const char *s)
5ff904cd
JL
124{
125 for (; *s != '\0'; ++s)
126 bufi = ffebad_bufputc_ (buf, bufi, *s);
127 return bufi;
128}
129
130/* ffebad_init_0 -- Initialize
131
132 ffebad_init_0(); */
133
134void
77f9b92c 135ffebad_init_0 (void)
5ff904cd
JL
136{
137 assert (FFEBAD == ARRAY_SIZE (ffebad_messages_));
138}
139
140ffebadSeverity
141ffebad_severity (ffebad errnum)
142{
143 return ffebad_messages_[errnum].severity;
144}
145
146/* ffebad_start_ -- Start displaying an error message
147
148 ffebad_start(FFEBAD_SOME_ERROR_CODE);
149
150 Call ffebad_start to establish the message, ffebad_here and ffebad_string
151 to send run-time data to it as necessary, then ffebad_finish when through
152 to actually get it to print (to stderr).
153
154 Note: ffebad_start(errnum) turns into ffebad_start_(FALSE,errnum). No
155 outside caller should call ffebad_start_ directly (as indicated by the
156 trailing underscore).
157
158 Call ffebad_start to start a normal message, one that might be inhibited
159 by the current state of statement guessing. Call ffebad_start_lex
160 instead to start a message that is global to all statement guesses and
161 happens only once for all guesses (i.e. the lexer).
162
163 sev and message are overrides for the severity and messages when errnum
164 is FFEBAD, meaning the caller didn't want to have to put a message in
165 bad.def to produce a diagnostic. */
166
167bool
168ffebad_start_ (bool lex_override, ffebad errnum, ffebadSeverity sev,
f1685b7c 169 const char *msgid)
5ff904cd
JL
170{
171 unsigned char i;
172
173 if (ffebad_is_inhibited_ && !lex_override)
174 {
175 ffebad_is_temp_inhibited_ = TRUE;
176 return FALSE;
177 }
178
179 if (errnum != FFEBAD)
180 {
181 ffebad_severity_ = ffebad_messages_[errnum].severity;
f1685b7c 182 ffebad_message_ = gettext (ffebad_messages_[errnum].message);
5ff904cd
JL
183 }
184 else
185 {
186 ffebad_severity_ = sev;
f1685b7c 187 ffebad_message_ = gettext (msgid);
5ff904cd
JL
188 }
189
516b69ff
RH
190 switch (ffebad_severity_)
191 { /* Tell toplev.c about this message. */
192 case FFEBAD_severityINFORMATIONAL:
193 case FFEBAD_severityTRIVIAL:
194 if (inhibit_warnings)
195 { /* User wants no warnings. */
196 ffebad_is_temp_inhibited_ = TRUE;
197 return FALSE;
198 }
199 /* Fall through. */
200 case FFEBAD_severityWARNING:
201 case FFEBAD_severityPECULIAR:
202 case FFEBAD_severityPEDANTIC:
203 if ((ffebad_severity_ != FFEBAD_severityPEDANTIC)
204 || !flag_pedantic_errors)
205 {
9804f5fb 206 if (!diagnostic_report_warnings_p ())
516b69ff
RH
207 { /* User wants no warnings. */
208 ffebad_is_temp_inhibited_ = TRUE;
209 return FALSE;
210 }
9804f5fb 211 diagnostic_kind_count (global_dc, DK_WARNING)++;
516b69ff
RH
212 break;
213 }
214 /* Fall through (PEDANTIC && flag_pedantic_errors). */
215 case FFEBAD_severityFATAL:
216 case FFEBAD_severityWEIRD:
217 case FFEBAD_severitySEVERE:
218 case FFEBAD_severityDISASTER:
9804f5fb 219 diagnostic_kind_count (global_dc, DK_ERROR)++;
516b69ff 220 break;
5ff904cd 221
516b69ff
RH
222 default:
223 break;
224 }
5ff904cd
JL
225
226 ffebad_is_temp_inhibited_ = FALSE;
227 ffebad_errnum_ = errnum;
228 ffebad_index_ = 0;
229 ffebad_places_ = 0;
230 for (i = 0; i < FFEBAD_MAX_; ++i)
231 {
232 ffebad_string_[i] = NULL;
233 ffebad_here_[i].line = ffewhere_line_unknown ();
234 ffebad_here_[i].col = ffewhere_column_unknown ();
235 }
236
237 return TRUE;
238}
239
240/* ffebad_here -- Establish source location of some diagnostic concern
241
242 ffebad_here(ffebadIndex i,ffewhereLine line,ffewhereColumn col);
243
244 Call ffebad_start to establish the message, ffebad_here and ffebad_string
245 to send run-time data to it as necessary, then ffebad_finish when through
246 to actually get it to print (to stderr). */
247
248void
249ffebad_here (ffebadIndex index, ffewhereLine line, ffewhereColumn col)
250{
251 ffewhereLineNumber line_num;
252 ffewhereLineNumber ln;
253 ffewhereColumnNumber col_num;
254 ffewhereColumnNumber cn;
255 ffebadIndex i;
256 ffebadIndex j;
257
258 if (ffebad_is_temp_inhibited_)
259 return;
260
261 assert (index < FFEBAD_MAX_);
262 ffebad_here_[index].line = ffewhere_line_use (line);
263 ffebad_here_[index].col = ffewhere_column_use (col);
264 if (ffewhere_line_is_unknown (line)
265 || ffewhere_column_is_unknown (col))
266 {
267 ffebad_here_[index].tag = FFEBAD_MAX_;
268 return;
269 }
270 ffebad_here_[index].tag = 0; /* For now, though it shouldn't matter. */
271
272 /* Sort the source line/col points into the order they occur in the source
273 file. Deal with duplicates appropriately. */
274
275 line_num = ffewhere_line_number (line);
276 col_num = ffewhere_column_number (col);
277
278 /* Determine where in the ffebad_order_ array this new place should go. */
279
280 for (i = 0; i < ffebad_places_; ++i)
281 {
282 ln = ffewhere_line_number (ffebad_here_[ffebad_order_[i]].line);
283 cn = ffewhere_column_number (ffebad_here_[ffebad_order_[i]].col);
284 if (line_num < ln)
285 break;
286 if (line_num == ln)
287 {
288 if (col_num == cn)
289 {
290 ffebad_here_[index].tag = i;
291 return; /* Shouldn't go in, has equivalent. */
292 }
293 else if (col_num < cn)
294 break;
295 }
296 }
297
298 /* Before putting new place in ffebad_order_[i], first increment all tags
299 that are i or greater. */
300
301 if (i != ffebad_places_)
302 {
303 for (j = 0; j < FFEBAD_MAX_; ++j)
304 {
305 if (ffebad_here_[j].tag >= i)
306 ++ffebad_here_[j].tag;
307 }
308 }
309
310 /* Then slide all ffebad_order_[] entries at and above i up one entry. */
311
312 for (j = ffebad_places_; j > i; --j)
313 ffebad_order_[j] = ffebad_order_[j - 1];
314
315 /* Finally can put new info in ffebad_order_[i]. */
316
317 ffebad_order_[i] = index;
318 ffebad_here_[index].tag = i;
319 ++ffebad_places_;
320}
321
322/* Establish string for next index (always in order) of message
323
26f096f9 324 ffebad_string(const char *string);
5ff904cd
JL
325
326 Call ffebad_start to establish the message, ffebad_here and ffebad_string
327 to send run-time data to it as necessary, then ffebad_finish when through
328 to actually get it to print (to stderr). Note: don't trash the string
329 until after calling ffebad_finish, since we just maintain a pointer to
330 the argument passed in until then. */
331
332void
26f096f9 333ffebad_string (const char *string)
5ff904cd
JL
334{
335 if (ffebad_is_temp_inhibited_)
336 return;
337
338 assert (ffebad_index_ != FFEBAD_MAX_);
339 ffebad_string_[ffebad_index_++] = string;
340}
341
342/* ffebad_finish -- Display error message with where & run-time info
343
344 ffebad_finish();
345
346 Call ffebad_start to establish the message, ffebad_here and ffebad_string
347 to send run-time data to it as necessary, then ffebad_finish when through
348 to actually get it to print (to stderr). */
349
350void
77f9b92c 351ffebad_finish (void)
5ff904cd
JL
352{
353#define MAX_SPACES 132
83182544 354 static const char *const spaces
5ff904cd
JL
355 = "...>\
356\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
357\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
358\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
359\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
360\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
361\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
362\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
363\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\
364\040\040\040"; /* MAX_SPACES - 1 spaces. */
365 ffewhereLineNumber last_line_num;
366 ffewhereLineNumber ln;
367 ffewhereLineNumber rn;
368 ffewhereColumnNumber last_col_num;
369 ffewhereColumnNumber cn;
370 ffewhereColumnNumber cnt;
371 ffewhereLine l;
372 ffebadIndex bi;
373 unsigned short i;
374 char pointer;
0816ebdd 375 unsigned char c;
26f096f9
KG
376 unsigned const char *s;
377 const char *fn;
5ff904cd
JL
378 static char buf[1024];
379 int bufi;
380 int index;
381
382 if (ffebad_is_temp_inhibited_)
383 return;
384
385 switch (ffebad_severity_)
386 {
387 case FFEBAD_severityINFORMATIONAL:
f1685b7c 388 s = _("note:");
5ff904cd
JL
389 break;
390
391 case FFEBAD_severityWARNING:
f1685b7c 392 s = _("warning:");
5ff904cd
JL
393 break;
394
395 case FFEBAD_severitySEVERE:
f1685b7c 396 s = _("fatal:");
5ff904cd
JL
397 break;
398
399 default:
400 s = "";
401 break;
402 }
403
404 /* Display the annoying source references. */
405
406 last_line_num = 0;
407 last_col_num = 0;
408
409 for (bi = 0; bi < ffebad_places_; ++bi)
410 {
411 if (ffebad_places_ == 1)
412 pointer = '^';
413 else
414 pointer = '1' + bi;
415
416 l = ffebad_here_[ffebad_order_[bi]].line;
417 ln = ffewhere_line_number (l);
418 rn = ffewhere_line_filelinenum (l);
419 cn = ffewhere_column_number (ffebad_here_[ffebad_order_[bi]].col);
420 fn = ffewhere_line_filename (l);
421 if (ln != last_line_num)
422 {
423 if (bi != 0)
424 fputc ('\n', stderr);
47b69537 425 diagnostic_report_current_function (global_dc);
5ff904cd 426 fprintf (stderr,
5ff904cd
JL
427 /* the trailing space on the <file>:<line>: line
428 fools emacs19 compilation mode into finding the
429 report */
430 "%s:%" ffewhereLineNumber_f "u: %s\n %s\n %s%c",
431 fn, rn,
5ff904cd
JL
432 s,
433 ffewhere_line_content (l),
434 &spaces[cn > MAX_SPACES ? 0 : MAX_SPACES - cn + 4],
435 pointer);
436 last_line_num = ln;
437 last_col_num = cn;
f1685b7c 438 s = _("(continued):");
5ff904cd
JL
439 }
440 else
441 {
442 cnt = cn - last_col_num;
443 fprintf (stderr,
444 "%s%c", &spaces[cnt > MAX_SPACES
445 ? 0 : MAX_SPACES - cnt + 4],
446 pointer);
447 last_col_num = cn;
448 }
449 }
450 if (ffebad_places_ == 0)
451 {
452 /* Didn't output "warning:" string, capitalize it for message. */
f6bbde28 453 if (s[0] != '\0')
5ff904cd
JL
454 {
455 char c;
456
92a438d1 457 c = TOUPPER (s[0]);
5ff904cd
JL
458 fprintf (stderr, "%c%s ", c, &s[1]);
459 }
460 else if (s[0] != '\0')
461 fprintf (stderr, "%s ", s);
462 }
463 else
464 fputc ('\n', stderr);
465
466 /* Release the ffewhere info. */
467
468 for (bi = 0; bi < FFEBAD_MAX_; ++bi)
469 {
470 ffewhere_line_kill (ffebad_here_[bi].line);
471 ffewhere_column_kill (ffebad_here_[bi].col);
472 }
473
474 /* Now display the message. */
475
476 bufi = 0;
477 for (i = 0; (c = ffebad_message_[i]) != '\0'; ++i)
478 {
479 if (c == '%')
480 {
481 c = ffebad_message_[++i];
0df6c2c7 482 if (ISUPPER (c))
5ff904cd
JL
483 {
484 index = c - 'A';
485
486 if ((index < 0) || (index >= FFEBAD_MAX_))
487 {
f1685b7c 488 bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!] %"));
5ff904cd
JL
489 bufi = ffebad_bufputc_ (buf, bufi, c);
490 }
491 else
492 {
493 s = ffebad_string_[index];
494 if (s == NULL)
f1685b7c 495 bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!]"));
5ff904cd
JL
496 else
497 bufi = ffebad_bufputs_ (buf, bufi, s);
498 }
499 }
8b45da67 500 else if (ISDIGIT (c))
5ff904cd
JL
501 {
502 index = c - '0';
503
504 if ((index < 0) || (index >= FFEBAD_MAX_))
505 {
f1685b7c 506 bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!] %"));
5ff904cd
JL
507 bufi = ffebad_bufputc_ (buf, bufi, c);
508 }
509 else
510 {
511 pointer = ffebad_here_[index].tag + '1';
512 if (pointer == FFEBAD_MAX_ + '1')
513 pointer = '?';
514 else if (ffebad_places_ == 1)
515 pointer = '^';
516 bufi = ffebad_bufputc_ (buf, bufi, '(');
517 bufi = ffebad_bufputc_ (buf, bufi, pointer);
518 bufi = ffebad_bufputc_ (buf, bufi, ')');
519 }
520 }
521 else if (c == '\0')
522 break;
523 else if (c == '%')
524 bufi = ffebad_bufputc_ (buf, bufi, '%');
525 else
526 {
f1685b7c 527 bufi = ffebad_bufputs_ (buf, bufi, _("[REPORT BUG!!]"));
5ff904cd
JL
528 bufi = ffebad_bufputc_ (buf, bufi, '%');
529 bufi = ffebad_bufputc_ (buf, bufi, c);
530 }
531 }
532 else
533 bufi = ffebad_bufputc_ (buf, bufi, c);
534 }
535 bufi = ffebad_bufputc_ (buf, bufi, '\n');
536 bufi = ffebad_bufflush_ (buf, bufi);
537}