This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
better error reporting for genfoo
- To: gcc-patches at gcc dot gnu dot org
- Subject: better error reporting for genfoo
- From: Richard Henderson <rth at cygnus dot com>
- Date: Wed, 13 Oct 1999 20:55:18 -0700
As genrecog et al get smarter about validating the md file, it
gets more and more irritating to find the problem given the
extraordinarily lame error messages we give.
Well, no more. Now, for the following input
(define_insn "mismatch"
[(set (match_operand:SI 0 "general_operand" "")
(match_operand:DI 1 "general_operand" ""))]
"" "")
(define_insn "unknown"
[(use (match_operand 0 "unknown_predicate" ""))]
"" "")
(define_insn "dup1"
[(use (const_int 1))]
"" "")
(define_insn "dup2"
[(use (const_int 1))]
"" "")
(define_insn "error"
[(set (match_operand:SI "general_operand" "")
(match_operand:SI 1 "general_operand" ""))]
"" "")
we'll get something sensible:
/home/rth/dummy:1: mode mismatch in set: SImode vs DImode
/home/rth/dummy:1: warning: `general_operand' accepts const_int,
/home/rth/dummy:1: and used as destination of a set
/home/rth/dummy:6: warning: `unknown_predicate' not in PREDICATE_CODES
/home/rth/dummy:14: `dup2' matches `dup1'
/home/rth/dummy:10: previous definition of `dup1'
/home/rth/dummy:19: missing name or number
/home/rth/dummy:19: following context is `"general_operand" "")'
In my fumble-fingered opinion, this is way way overdue.
r~
* rtl.c (dump_and_abort): Remove.
(fatal_with_file_and_line): New.
(fatal_expected_char): New.
(read_rtx_lineno, read_rtx_filename): New.
(read_skip_spaces): Track line number.
(read_name): Use fatal_with_file_and_line.
(read_rtx): Use fatal_expected_char. Track line number.
* rtl.h (read_rtx_filename, read_rtx_lineno): Declare.
* print-rtl.c (print_rtx): Don't special case LABEL_REF argument
if it isn't a CODE_LABEL.
* genattr.c (main): Set read_rtx_filename.
* genattrtab.c (main): Likewise.
* gencodes.c (main): Likewise.
* genconfig.c (main): Likewise.
* genemit.c (main): Likewise.
* genextract.c (main): Likewise.
* genflags.c (main): Likewise.
* genopinit.c (main): Likewise.
* genoutput.c (main): Likewise.
* genpeep.c (main): Likewise.
* genrecog.c (decision_test.u.insn): Add `lineno'.
(pattern_lineno, error_count): New variables.
(message_with_line): New.
(add_to_sequence): Break out checking code to ...
(validate_pattern): ... here. Detect SET_DEST matching CONST_INT.
(merge_insn): Use message_with_line.
(make_insn_sequence): Use validate_pattern. Record insn lineno.
(main): Set read_rtx_filename, pattern_lineno. Exit early on error.
Index: genattr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genattr.c,v
retrieving revision 1.28
diff -c -p -d -r1.28 genattr.c
*** genattr.c 1999/09/16 22:20:41 1.28
--- genattr.c 1999/10/14 03:34:33
*************** main (argc, argv)
*** 251,256 ****
--- 251,257 ----
perror (argv[1]);
return (FATAL_EXIT_CODE);
}
+ read_rtx_filename = argv[1];
printf ("/* Generated automatically by the program `genattr'\n\
from the machine description file `md'. */\n\n");
Index: genattrtab.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genattrtab.c,v
retrieving revision 1.67
diff -c -p -d -r1.67 genattrtab.c
*** genattrtab.c 1999/10/04 06:08:16 1.67
--- genattrtab.c 1999/10/14 03:34:33
*************** main (argc, argv)
*** 6000,6005 ****
--- 6000,6006 ----
perror (argv[1]);
return (FATAL_EXIT_CODE);
}
+ read_rtx_filename = argv[1];
/* Set up true and false rtx's */
true_rtx = rtx_alloc (CONST_INT);
Index: gencodes.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gencodes.c,v
retrieving revision 1.24
diff -c -p -d -r1.24 gencodes.c
*** gencodes.c 1999/09/15 14:13:46 1.24
--- gencodes.c 1999/10/14 03:34:33
*************** main (argc, argv)
*** 98,103 ****
--- 98,104 ----
perror (argv[1]);
return (FATAL_EXIT_CODE);
}
+ read_rtx_filename = argv[1];
printf ("/* Generated automatically by the program `gencodes'\n\
from the machine description file `md'. */\n\n");
Index: genconfig.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genconfig.c,v
retrieving revision 1.28
diff -c -p -d -r1.28 genconfig.c
*** genconfig.c 1999/10/06 17:22:54 1.28
--- genconfig.c 1999/10/14 03:34:33
*************** main (argc, argv)
*** 297,302 ****
--- 297,303 ----
perror (argv[1]);
return (FATAL_EXIT_CODE);
}
+ read_rtx_filename = argv[1];
printf ("/* Generated automatically by the program `genconfig'\n\
from the machine description file `md'. */\n\n");
Index: genemit.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genemit.c,v
retrieving revision 1.47
diff -c -p -d -r1.47 genemit.c
*** genemit.c 1999/09/20 09:59:56 1.47
--- genemit.c 1999/10/14 03:34:33
*************** main (argc, argv)
*** 787,792 ****
--- 787,793 ----
perror (argv[1]);
return (FATAL_EXIT_CODE);
}
+ read_rtx_filename = argv[1];
/* Assign sequential codes to all entries in the machine description
in parallel with the tables in insn-output.c. */
Index: genextract.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genextract.c,v
retrieving revision 1.35
diff -c -p -d -r1.35 genextract.c
*** genextract.c 1999/09/15 14:13:47 1.35
--- genextract.c 1999/10/14 03:34:33
*************** main (argc, argv)
*** 400,405 ****
--- 400,406 ----
perror (argv[1]);
return (FATAL_EXIT_CODE);
}
+ read_rtx_filename = argv[1];
/* Assign sequential codes to all entries in the machine description
in parallel with the tables in insn-output.c. */
Index: genflags.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genflags.c,v
retrieving revision 1.24
diff -c -p -d -r1.24 genflags.c
*** genflags.c 1999/09/15 14:13:48 1.24
--- genflags.c 1999/10/14 03:34:33
*************** main (argc, argv)
*** 224,229 ****
--- 224,230 ----
perror (argv[1]);
return (FATAL_EXIT_CODE);
}
+ read_rtx_filename = argv[1];
printf ("/* Generated automatically by the program `genflags'\n\
from the machine description file `md'. */\n\n");
Index: genopinit.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genopinit.c,v
retrieving revision 1.32
diff -c -p -d -r1.32 genopinit.c
*** genopinit.c 1999/09/23 11:34:49 1.32
--- genopinit.c 1999/10/14 03:34:33
*************** main (argc, argv)
*** 327,332 ****
--- 327,333 ----
perror (argv[1]);
return (FATAL_EXIT_CODE);
}
+ read_rtx_filename = argv[1];
printf ("/* Generated automatically by the program `genopinit'\n\
from the machine description file `md'. */\n\n");
Index: genoutput.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genoutput.c,v
retrieving revision 1.37
diff -c -p -d -r1.37 genoutput.c
*** genoutput.c 1999/10/12 03:28:42 1.37
--- genoutput.c 1999/10/14 03:34:33
*************** main (argc, argv)
*** 907,912 ****
--- 907,913 ----
perror (argv[1]);
return (FATAL_EXIT_CODE);
}
+ read_rtx_filename = argv[1];
output_prologue ();
next_code_number = 0;
Index: genpeep.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genpeep.c,v
retrieving revision 1.37
diff -c -p -d -r1.37 genpeep.c
*** genpeep.c 1999/09/23 17:46:22 1.37
--- genpeep.c 1999/10/14 03:34:33
*************** main (argc, argv)
*** 424,429 ****
--- 424,430 ----
perror (argv[1]);
return (FATAL_EXIT_CODE);
}
+ read_rtx_filename = argv[1];
printf ("/* Generated automatically by the program `genpeep'\n\
from the machine description file `md'. */\n\n");
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genrecog.c,v
retrieving revision 1.60
diff -c -p -d -r1.60 genrecog.c
*** genrecog.c 1999/10/13 17:22:40 1.60
--- genrecog.c 1999/10/14 03:34:33
*************** struct decision_test
*** 115,120 ****
--- 115,121 ----
struct {
int code_number; /* Insn number matched. */
+ int lineno; /* Line number of the insn. */
int num_clobbers_to_add; /* Number of CLOBBERs to be added. */
} insn;
} u;
*************** static int next_index;
*** 170,175 ****
--- 171,182 ----
allocate in each subroutine we make. */
static int max_depth;
+
+ /* The line number of the start of the pattern currently being processed. */
+ static int pattern_lineno;
+
+ /* Count of errors. */
+ static int error_count;
/* This table contains a list of the rtl codes that can possibly match a
predicate defined in recog.c. The function `maybe_both_true' uses it to
*************** static struct decision *new_decision
*** 213,218 ****
--- 220,227 ----
PROTO((const char *, struct decision_head *));
static struct decision_test *new_decision_test
PROTO((enum decision_type, struct decision_test ***));
+ static void validate_pattern
+ PROTO((rtx, int));
static struct decision *add_to_sequence
PROTO((rtx, struct decision_head *, const char *, enum routine_type, int));
*************** static void debug_decision_2
*** 284,289 ****
--- 293,321 ----
extern void debug_decision
PROTO((struct decision *));
+ static void
+ message_with_line VPROTO ((int lineno, const char *msg, ...))
+ {
+ #ifndef ANSI_PROTOTYPES
+ int lineno;
+ const char *msg;
+ #endif
+ va_list ap;
+
+ VA_START (ap, msg);
+
+ #ifndef ANSI_PROTOTYPES
+ lineno = va_arg (ap, int);
+ msg = va_arg (ap, const char *);
+ #endif
+
+ fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
+ vfprintf (stderr, msg, ap);
+ fputc ('\n', stderr);
+
+ va_end (ap);
+ }
+
/* Create a new node in sequence after LAST. */
static struct decision *
*************** new_decision_test (type, pplace)
*** 324,329 ****
--- 356,497 ----
return test;
}
+ /* Check for various errors in patterns. */
+
+ static void
+ validate_pattern (pattern, set_dest)
+ rtx pattern;
+ int set_dest;
+ {
+ const char *fmt;
+ RTX_CODE code;
+ int i, j, len;
+
+ code = GET_CODE (pattern);
+ switch (code)
+ {
+ case MATCH_SCRATCH:
+ case MATCH_INSN:
+ return;
+
+ case MATCH_OPERAND:
+ {
+ const char *pred_name = XSTR (pattern, 1);
+
+ if (pred_name[0] != 0)
+ {
+ /* See if we know about this predicate and save its number. If
+ we do, and it only accepts one code, note that fact. The
+ predicate `const_int_operand' only tests for a CONST_INT, so
+ if we do so we can avoid calling it at all.
+
+ Finally, if we know that the predicate does not allow
+ CONST_INT, we know that the only way the predicate can match
+ is if the modes match (here we use the kludge of relying on
+ the fact that "address_operand" accepts CONST_INT; otherwise,
+ it would have to be a special case), so we can test the mode
+ (but we need not). This fact should considerably simplify the
+ generated code. */
+
+ for (i = 0; i < (int) NUM_KNOWN_PREDS; i++)
+ if (! strcmp (preds[i].name, pred_name))
+ break;
+
+ if (i < (int) NUM_KNOWN_PREDS)
+ {
+ int j, allows_const_int;
+
+ allows_const_int = 0;
+ for (j = 0; preds[i].codes[j] != 0; j++)
+ if (preds[i].codes[j] == CONST_INT)
+ {
+ allows_const_int = 1;
+ break;
+ }
+
+ if (allows_const_int && set_dest)
+ {
+ message_with_line (pattern_lineno,
+ "warning: `%s' accepts const_int,",
+ pred_name);
+ message_with_line (pattern_lineno,
+ " and used as destination of a set");
+ }
+ }
+ else
+ {
+ #ifdef PREDICATE_CODES
+ /* If the port has a list of the predicates it uses but
+ omits one, warn. */
+ message_with_line (pattern_lineno, "warning: `%s' not in PREDICATE_CODES", pred_name);
+ #endif
+ }
+ }
+
+ return;
+ }
+
+ case SET:
+ /* The operands of a SET must have the same mode unless one
+ is VOIDmode. */
+ if (GET_MODE (SET_SRC (pattern)) != VOIDmode
+ && GET_MODE (SET_DEST (pattern)) != VOIDmode
+ && GET_MODE (SET_SRC (pattern)) != GET_MODE (SET_DEST (pattern))
+ /* The mode of an ADDRESS_OPERAND is the mode of the memory
+ reference, not the mode of the address. */
+ && ! (GET_CODE (SET_SRC (pattern)) == MATCH_OPERAND
+ && ! strcmp (XSTR (SET_SRC (pattern), 1), "address_operand")))
+ {
+ message_with_line (pattern_lineno,
+ "mode mismatch in set: %smode vs %smode",
+ GET_MODE_NAME (GET_MODE (SET_DEST (pattern))),
+ GET_MODE_NAME (GET_MODE (SET_SRC (pattern))));
+ error_count++;
+ }
+
+ validate_pattern (SET_DEST (pattern), 1);
+ validate_pattern (SET_SRC (pattern), 0);
+ return;
+
+ case LABEL_REF:
+ if (GET_MODE (XEXP (pattern, 0)) != VOIDmode)
+ {
+ message_with_line (pattern_lineno,
+ "operand to label_ref %smode not VOIDmode",
+ GET_MODE_NAME (GET_MODE (XEXP (pattern, 0))));
+ error_count++;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ fmt = GET_RTX_FORMAT (code);
+ len = GET_RTX_LENGTH (code);
+ for (i = 0; i < len; i++)
+ {
+ switch (fmt[i])
+ {
+ case 'e': case 'u':
+ validate_pattern (XEXP (pattern, i), 0);
+ break;
+
+ case 'E':
+ for (j = 0; j < XVECLEN (pattern, i); j++)
+ validate_pattern (XVECEXP (pattern, i, j), 0);
+ break;
+
+ case 'i': case 'w': case '0': case 's':
+ break;
+
+ default:
+ abort ();
+ }
+ }
+
+ }
+
/* Create a chain of nodes to verify that an rtl expression matches
PATTERN.
*************** add_to_sequence (pattern, last, position
*** 465,479 ****
}
}
else
! {
! test->u.pred.index = -1;
! #ifdef PREDICATE_CODES
! /* If the port has a list of the predicates it uses but
! omits one, warn. */
! fprintf (stderr, "Warning: `%s' not in PREDICATE_CODES\n",
! pred_name);
! #endif
! }
}
/* Can't enforce a mode if we allow const_int. */
--- 633,639 ----
}
}
else
! test->u.pred.index = -1;
}
/* Can't enforce a mode if we allow const_int. */
*************** add_to_sequence (pattern, last, position
*** 526,557 ****
pattern = XEXP (pattern, 0);
goto restart;
- case SET:
- /* The operands of a SET must have the same mode unless one
- is VOIDmode. */
- if (GET_MODE (SET_SRC (pattern)) != VOIDmode
- && GET_MODE (SET_DEST (pattern)) != VOIDmode
- && GET_MODE (SET_SRC (pattern)) != GET_MODE (SET_DEST (pattern))
- /* The mode of an ADDRESS_OPERAND is the mode of the memory
- reference, not the mode of the address. */
- && ! (GET_CODE (SET_SRC (pattern)) == MATCH_OPERAND
- && ! strcmp (XSTR (SET_SRC (pattern), 1), "address_operand")))
- {
- print_rtl (stderr, pattern);
- fputc ('\n', stderr);
- fatal ("mode mismatch in SET");
- }
- break;
-
- case LABEL_REF:
- if (GET_MODE (XEXP (pattern, 0)) != VOIDmode)
- {
- print_rtl (stderr, pattern);
- fputc ('\n', stderr);
- fatal ("operand to LABEL_REF not VOIDmode");
- }
- break;
-
default:
break;
}
--- 686,691 ----
*************** merge_accept_insn (oldd, addd)
*** 966,976 ****
}
else
{
! fatal ("Two actions at one point in tree for insns \"%s\" (%d) and \"%s\" (%d)",
! get_insn_name (old->u.insn.code_number),
! old->u.insn.code_number,
! get_insn_name (add->u.insn.code_number),
! add->u.insn.code_number);
}
}
--- 1100,1111 ----
}
else
{
! message_with_line (add->u.insn.lineno, "`%s' matches `%s'",
! get_insn_name (add->u.insn.code_number),
! get_insn_name (old->u.insn.code_number));
! message_with_line (old->u.insn.lineno, "previous definition of `%s'",
! get_insn_name (old->u.insn.code_number));
! error_count++;
}
}
*************** make_insn_sequence (insn, type)
*** 2015,2020 ****
--- 2150,2157 ----
PUT_MODE (x, VOIDmode);
}
+ validate_pattern (x, 0);
+
memset(&head, 0, sizeof(head));
last = add_to_sequence (x, &head, "", type, 1);
*************** make_insn_sequence (insn, type)
*** 2037,2042 ****
--- 2174,2180 ----
test = new_decision_test (DT_accept_insn, &place);
test->u.insn.code_number = next_insn_code;
+ test->u.insn.lineno = pattern_lineno;
test->u.insn.num_clobbers_to_add = 0;
switch (type)
*************** make_insn_sequence (insn, type)
*** 2103,2108 ****
--- 2241,2247 ----
test = new_decision_test (DT_accept_insn, &place);
test->u.insn.code_number = next_insn_code;
+ test->u.insn.lineno = pattern_lineno;
test->u.insn.num_clobbers_to_add = XVECLEN (x, 0) - i;
merge_trees (&head, &clobber_head);
*************** main (argc, argv)
*** 2171,2176 ****
--- 2310,2316 ----
perror (argv[1]);
return FATAL_EXIT_CODE;
}
+ read_rtx_filename = argv[1];
next_insn_code = 0;
next_index = 0;
*************** main (argc, argv)
*** 2185,2190 ****
--- 2325,2331 ----
if (c == EOF)
break;
ungetc (c, infile);
+ pattern_lineno = read_rtx_lineno;
desc = read_rtx (infile);
if (GET_CODE (desc) == DEFINE_INSN)
*************** main (argc, argv)
*** 2208,2213 ****
--- 2349,2357 ----
next_insn_code++;
next_index++;
}
+
+ if (error_count)
+ return FATAL_EXIT_CODE;
puts ("\n\n");
Index: print-rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/print-rtl.c,v
retrieving revision 1.36
diff -c -p -d -r1.36 print-rtl.c
*** print-rtl.c 1999/09/15 23:05:04 1.36
--- print-rtl.c 1999/10/14 03:34:33
*************** print_rtx (in_rtx)
*** 200,205 ****
--- 200,206 ----
break;
case 'e':
+ do_e:
indent += 2;
if (!sawclose)
fprintf (outfile, " ");
*************** print_rtx (in_rtx)
*** 298,303 ****
--- 299,307 ----
case 'u':
if (XEXP (in_rtx, i) != NULL)
{
+ if (GET_CODE (XEXP (in_rtx, i)) != CODE_LABEL)
+ goto do_e;
+
if (flag_dump_unnumbered)
fputc ('#', outfile);
else
Index: rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.c,v
retrieving revision 1.48
diff -c -p -d -r1.48 rtl.c
*** rtl.c 1999/10/11 18:42:36 1.48
--- rtl.c 1999/10/14 03:34:33
*************** const char * const reg_note_name[] = { "
*** 259,265 ****
"REG_FRAME_RELATED_EXPR", "REG_EH_REGION",
"REG_EH_RETHROW", "REG_SAVE_NOTE" };
! static void dump_and_abort PROTO((int, int, FILE *)) ATTRIBUTE_NORETURN;
static void read_name PROTO((char *, FILE *));
static const char *trim_filename PROTO((const char *));
--- 259,267 ----
"REG_FRAME_RELATED_EXPR", "REG_EH_REGION",
"REG_EH_RETHROW", "REG_SAVE_NOTE" };
! static void fatal_with_file_and_line PVPROTO((FILE *, const char *, ...))
! ATTRIBUTE_NORETURN;
! static void fatal_expected_char PROTO((FILE *, int, int)) ATTRIBUTE_NORETURN;
static void read_name PROTO((char *, FILE *));
static const char *trim_filename PROTO((const char *));
*************** shallow_copy_rtx (orig)
*** 582,613 ****
/* Subroutines of read_rtx. */
! /* Dump code after printing a message. Used when read_rtx finds
! invalid data. */
static void
! dump_and_abort (expected_c, actual_c, infile)
! int expected_c, actual_c;
! FILE *infile;
{
! int c, i;
! if (expected_c >= 0)
! fprintf (stderr,
! "Expected character %c. Found character %c.",
! expected_c, actual_c);
! fprintf (stderr, " At file position: %ld\n", ftell (infile));
! fprintf (stderr, "Following characters are:\n\t");
! for (i = 0; i < 200; i++)
{
c = getc (infile);
! if (EOF == c) break;
! putc (c, stderr);
}
! fprintf (stderr, "Aborting.\n");
! abort ();
}
/* Read chars from INFILE until a non-whitespace char
and return that. Comments, both Lisp style and C style,
are treated as whitespace.
--- 584,649 ----
/* Subroutines of read_rtx. */
! /* The current line number for the file. */
! int read_rtx_lineno = 1;
+ /* The filename for aborting with file and line. */
+ const char *read_rtx_filename = "<unknown>";
+
static void
! fatal_with_file_and_line VPROTO((FILE *infile, const char *msg, ...))
{
! #ifndef ANSI_PROTOTYPES
! FILE *infile;
! const char *msg;
! #endif
! va_list ap;
! char context[64];
! size_t i;
! int c;
! VA_START (ap, msg);
!
! #ifndef ANSI_PROTOTYPES
! infile = va_arg (ap, FILE *);
! msg = va_arg (ap, const char *);
! #endif
!
! fprintf (stderr, "%s:%d: ", read_rtx_filename, read_rtx_lineno);
! vfprintf (stderr, msg, ap);
! putc ('\n', stderr);
!
! /* Gather some following context. */
! for (i = 0; i < sizeof(context)-1; ++i)
{
c = getc (infile);
! if (c == EOF)
! break;
! if (c == '\r' || c == '\n')
! break;
! context[i] = c;
}
! context[i] = '\0';
!
! fprintf (stderr, "%s:%d: following context is `%s'\n",
! read_rtx_filename, read_rtx_lineno, context);
!
! va_end (ap);
! exit (1);
}
+ /* Dump code after printing a message. Used when read_rtx finds
+ invalid data. */
+
+ static void
+ fatal_expected_char (infile, expected_c, actual_c)
+ FILE *infile;
+ int expected_c, actual_c;
+ {
+ fatal_with_file_and_line (infile, "expected character `%c', found `%c'",
+ expected_c, actual_c);
+ }
+
/* Read chars from INFILE until a non-whitespace char
and return that. Comments, both Lisp style and C style,
are treated as whitespace.
*************** read_skip_spaces (infile)
*** 618,650 ****
FILE *infile;
{
register int c;
! while ((c = getc (infile)))
{
! if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
! ;
! else if (c == ';')
! {
! while ((c = getc (infile)) && c != '\n' && c != EOF)
! ;
! }
! else if (c == '/')
{
! register int prevc;
! c = getc (infile);
! if (c != '*')
! dump_and_abort ('*', c, infile);
! prevc = 0;
! while ((c = getc (infile)) && c != EOF)
! {
! if (prevc == '*' && c == '/')
! break;
! prevc = c;
! }
}
- else break;
}
- return c;
}
/* Read an rtx code name into the buffer STR[].
--- 654,701 ----
FILE *infile;
{
register int c;
! while (1)
{
! c = getc (infile);
! switch (c)
{
! case '\n':
! read_rtx_lineno++;
! break;
!
! case ' ': case '\t': case '\f': case '\r':
! break;
!
! case ';':
! do
! c = getc (infile);
! while (c != '\n' && c != EOF);
! read_rtx_lineno++;
! break;
!
! case '/':
! {
! register int prevc;
! c = getc (infile);
! if (c != '*')
! fatal_expected_char (infile, '*', c);
! prevc = 0;
! while ((c = getc (infile)) && c != EOF)
! {
! if (c == '\n')
! read_rtx_lineno++;
! else if (prevc == '*' && c == '/')
! break;
! prevc = c;
! }
! }
! break;
!
! default:
! return c;
}
}
}
/* Read an rtx code name into the buffer STR[].
*************** read_name (str, infile)
*** 675,684 ****
c = getc (infile);
}
if (p == str)
! {
! fprintf (stderr, "missing name or number");
! dump_and_abort (-1, -1, infile);
! }
*p = 0;
}
--- 726,734 ----
c = getc (infile);
}
if (p == str)
! fatal_with_file_and_line (infile, "missing name or number");
! if (c == '\n')
! read_rtx_lineno++;
*p = 0;
}
*************** read_rtx (infile)
*** 745,756 ****
struct rtx_list
{
struct rtx_list *next;
! rtx value; /* Value of this node... */
};
c = read_skip_spaces (infile); /* Should be open paren. */
if (c != '(')
! dump_and_abort ('(', c, infile);
read_name (tmp_char, infile);
--- 795,806 ----
struct rtx_list
{
struct rtx_list *next;
! rtx value; /* Value of this node. */
};
c = read_skip_spaces (infile); /* Should be open paren. */
if (c != '(')
! fatal_expected_char (infile, '(', c);
read_name (tmp_char, infile);
*************** read_rtx (infile)
*** 831,837 ****
c = read_skip_spaces (infile);
if (c != '[')
! dump_and_abort ('[', c, infile);
/* add expressions to a list, while keeping a count */
next_rtx = NULL;
--- 881,887 ----
c = read_skip_spaces (infile);
if (c != '[')
! fatal_expected_char (infile, '[', c);
/* add expressions to a list, while keeping a count */
next_rtx = NULL;
*************** read_rtx (infile)
*** 887,897 ****
c = read_skip_spaces (infile);
}
if (c != '"')
! dump_and_abort ('"', c, infile);
while (1)
{
c = getc (infile); /* Read the string */
if (c == '\\')
{
c = getc (infile); /* Read the string */
--- 937,949 ----
c = read_skip_spaces (infile);
}
if (c != '"')
! fatal_expected_char (infile, '"', c);
while (1)
{
c = getc (infile); /* Read the string */
+ if (c == '\n')
+ read_rtx_lineno++;
if (c == '\\')
{
c = getc (infile); /* Read the string */
*************** read_rtx (infile)
*** 916,922 ****
{
c = read_skip_spaces (infile);
if (c != ')')
! dump_and_abort (')', c, infile);
}
XSTR (return_rtx, i) = stringbuf;
}
--- 968,974 ----
{
c = read_skip_spaces (infile);
if (c != ')')
! fatal_expected_char (infile, ')', c);
}
XSTR (return_rtx, i) = stringbuf;
}
*************** read_rtx (infile)
*** 959,965 ****
c = read_skip_spaces (infile);
if (c != ')')
! dump_and_abort (')', c, infile);
return return_rtx;
}
--- 1011,1017 ----
c = read_skip_spaces (infile);
if (c != ')')
! fatal_expected_char (infile, ')', c);
return return_rtx;
}
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.144
diff -c -p -d -r1.144 rtl.h
*** rtl.h 1999/10/13 17:09:18 1.144
--- rtl.h 1999/10/14 03:34:33
*************** extern rtx gen_rtx PVPROTO((enum rtx_c
*** 963,972 ****
enum machine_mode, ...));
extern rtvec gen_rtvec PVPROTO((int, ...));
- #ifdef BUFSIZ
- extern rtx read_rtx PROTO((FILE *));
- #endif
-
extern char *oballoc PROTO((int));
extern char *permalloc PROTO((int));
extern rtx rtx_alloc PROTO((RTX_CODE));
--- 963,968 ----
*************** extern void gcc_obstack_init PROTO ((st
*** 1379,1388 ****
extern void pop_obstacks PROTO ((void));
extern void push_obstacks PROTO ((struct obstack *,
struct obstack *));
- #ifdef BUFSIZ
- extern int read_skip_spaces PROTO ((FILE *));
- #endif
-
/* In cse.c */
struct cse_basic_block_data;
extern int rtx_cost PROTO ((rtx, enum rtx_code));
--- 1375,1380 ----
*************** extern void rrotate_double PROTO ((HOST_
*** 1642,1648 ****
HOST_WIDE_INT *));
/* In calls.c */
- /* Emit library call. */
extern void emit_library_call PVPROTO ((rtx, int, enum machine_mode,
int, ...));
extern rtx emit_library_call_value PVPROTO((rtx, rtx, int,
--- 1634,1639 ----
*************** extern void init_varasm_once PROTO ((vo
*** 1661,1666 ****
--- 1652,1665 ----
/* In rtl.c */
extern void init_rtl PROTO ((void));
extern void rtx_free PROTO ((rtx));
+
+ #ifdef BUFSIZ
+ extern int read_skip_spaces PROTO ((FILE *));
+ extern rtx read_rtx PROTO ((FILE *));
+ #endif
+
+ extern const char *read_rtx_filename;
+ extern int read_rtx_lineno;
/* Redefine abort to report an internal error w/o coredump, and
reporting the location of the error in the source file. This logic