]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/read-md.c
re PR rtl-optimization/78617 (LRA clobbers live register during rematerialization)
[thirdparty/gcc.git] / gcc / read-md.c
CommitLineData
10692477 1/* MD reader for GCC.
818ab71a 2 Copyright (C) 1987-2016 Free Software Foundation, Inc.
10692477
RS
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20#include "bconfig.h"
21#include "system.h"
22#include "coretypes.h"
bb933490 23#include "errors.h"
b78027d1
DM
24#include "statistics.h"
25#include "vec.h"
10692477
RS
26#include "read-md.h"
27
28/* Associates PTR (which can be a string, etc.) with the file location
29 specified by FILENAME and LINENO. */
30struct ptr_loc {
31 const void *ptr;
32 const char *filename;
33 int lineno;
34};
35
600ab3fc
RS
36/* This callback will be invoked whenever an md include directive is
37 processed. To be used for creation of the dependency file. */
38void (*include_callback) (const char *);
39
812b1403
DM
40/* Global singleton. */
41
42rtx_reader *rtx_reader_ptr;
600ab3fc 43
9f418533
RS
44/* Given an object that starts with a char * name field, return a hash
45 code for its name. */
46
47hashval_t
48leading_string_hash (const void *def)
49{
50 return htab_hash_string (*(const char *const *) def);
51}
52
53/* Given two objects that start with char * name fields, return true if
54 they have the same name. */
55
56int
57leading_string_eq_p (const void *def1, const void *def2)
58{
59 return strcmp (*(const char *const *) def1,
60 *(const char *const *) def2) == 0;
61}
62
10692477
RS
63/* Return a hash value for the pointer pointed to by DEF. */
64
65static hashval_t
66leading_ptr_hash (const void *def)
67{
68 return htab_hash_pointer (*(const void *const *) def);
69}
70
71/* Return true if DEF1 and DEF2 are pointers to the same pointer. */
72
73static int
74leading_ptr_eq_p (const void *def1, const void *def2)
75{
76 return *(const void *const *) def1 == *(const void *const *) def2;
77}
78
79/* Associate PTR with the file position given by FILENAME and LINENO. */
80
b78027d1
DM
81void
82rtx_reader::set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
10692477
RS
83{
84 struct ptr_loc *loc;
85
b78027d1 86 loc = (struct ptr_loc *) obstack_alloc (&m_ptr_loc_obstack,
10692477
RS
87 sizeof (struct ptr_loc));
88 loc->ptr = ptr;
89 loc->filename = filename;
90 loc->lineno = lineno;
b78027d1 91 *htab_find_slot (m_ptr_locs, loc, INSERT) = loc;
10692477
RS
92}
93
94/* Return the position associated with pointer PTR. Return null if no
95 position was set. */
96
b78027d1
DM
97const struct ptr_loc *
98rtx_reader::get_md_ptr_loc (const void *ptr)
10692477 99{
b78027d1 100 return (const struct ptr_loc *) htab_find (m_ptr_locs, &ptr);
10692477
RS
101}
102
103/* Associate NEW_PTR with the same file position as OLD_PTR. */
104
105void
b78027d1 106rtx_reader::copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
10692477 107{
d2a3ce4e 108 const struct ptr_loc *loc = get_md_ptr_loc (old_ptr);
10692477 109 if (loc != 0)
d2a3ce4e 110 set_md_ptr_loc (new_ptr, loc->filename, loc->lineno);
10692477
RS
111}
112
113/* If PTR is associated with a known file position, print a #line
41723253 114 directive for it to OUTF. */
10692477
RS
115
116void
b78027d1 117rtx_reader::fprint_md_ptr_loc (FILE *outf, const void *ptr)
10692477 118{
d2a3ce4e 119 const struct ptr_loc *loc = get_md_ptr_loc (ptr);
10692477 120 if (loc != 0)
41723253
SB
121 fprintf (outf, "#line %d \"%s\"\n", loc->lineno, loc->filename);
122}
123
124/* Special fprint_md_ptr_loc for writing to STDOUT. */
125void
b78027d1 126rtx_reader::print_md_ptr_loc (const void *ptr)
41723253
SB
127{
128 fprint_md_ptr_loc (stdout, ptr);
10692477
RS
129}
130
131/* Return a condition that satisfies both COND1 and COND2. Either string
132 may be null or empty. */
133
134const char *
b78027d1 135rtx_reader::join_c_conditions (const char *cond1, const char *cond2)
10692477
RS
136{
137 char *result;
138 const void **entry;
139
140 if (cond1 == 0 || cond1[0] == 0)
141 return cond2;
142
143 if (cond2 == 0 || cond2[0] == 0)
144 return cond1;
145
146 if (strcmp (cond1, cond2) == 0)
147 return cond1;
148
149 result = concat ("(", cond1, ") && (", cond2, ")", NULL);
b78027d1
DM
150 obstack_ptr_grow (&m_joined_conditions_obstack, result);
151 obstack_ptr_grow (&m_joined_conditions_obstack, cond1);
152 obstack_ptr_grow (&m_joined_conditions_obstack, cond2);
153 entry = XOBFINISH (&m_joined_conditions_obstack, const void **);
154 *htab_find_slot (m_joined_conditions, entry, INSERT) = entry;
10692477
RS
155 return result;
156}
157
41723253
SB
158/* Print condition COND to OUTF, wrapped in brackets. If COND was created
159 by join_c_conditions, recursively invoke this function for the original
10692477
RS
160 conditions and join the result with "&&". Otherwise print a #line
161 directive for COND if its original file position is known. */
162
163void
b78027d1 164rtx_reader::fprint_c_condition (FILE *outf, const char *cond)
10692477 165{
b78027d1 166 const char **halves = (const char **) htab_find (m_joined_conditions, &cond);
10692477
RS
167 if (halves != 0)
168 {
41723253
SB
169 fprintf (outf, "(");
170 fprint_c_condition (outf, halves[1]);
171 fprintf (outf, " && ");
172 fprint_c_condition (outf, halves[2]);
173 fprintf (outf, ")");
10692477
RS
174 }
175 else
176 {
41723253
SB
177 fputc ('\n', outf);
178 fprint_md_ptr_loc (outf, cond);
179 fprintf (outf, "(%s)", cond);
10692477
RS
180 }
181}
182
41723253
SB
183/* Special fprint_c_condition for writing to STDOUT. */
184
185void
b78027d1 186rtx_reader::print_c_condition (const char *cond)
41723253
SB
187{
188 fprint_c_condition (stdout, cond);
189}
190
bb933490
RS
191/* A vfprintf-like function for reporting an error against line LINENO
192 of the current MD file. */
193
194static void ATTRIBUTE_PRINTF(2,0)
cc472607 195message_at_1 (file_location loc, const char *msg, va_list ap)
bb933490 196{
3814e880 197 fprintf (stderr, "%s:%d:%d: ", loc.filename, loc.lineno, loc.colno);
bb933490
RS
198 vfprintf (stderr, msg, ap);
199 fputc ('\n', stderr);
200}
201
cc472607
RS
202/* A printf-like function for reporting a message against location LOC. */
203
204void
205message_at (file_location loc, const char *msg, ...)
206{
207 va_list ap;
208
209 va_start (ap, msg);
210 message_at_1 (loc, msg, ap);
211 va_end (ap);
212}
213
214/* Like message_at, but treat the condition as an error. */
215
216void
217error_at (file_location loc, const char *msg, ...)
218{
219 va_list ap;
220
221 va_start (ap, msg);
222 message_at_1 (loc, msg, ap);
223 va_end (ap);
224 have_error = 1;
225}
226
8f246310
RS
227/* Like message_at, but treat the condition as a fatal error. */
228
229void
230fatal_at (file_location loc, const char *msg, ...)
231{
232 va_list ap;
233
234 va_start (ap, msg);
235 message_at_1 (loc, msg, ap);
236 va_end (ap);
237 exit (1);
238}
239
10692477 240/* A printf-like function for reporting an error against the current
c5e88b39 241 position in the MD file. */
10692477
RS
242
243void
c5e88b39 244fatal_with_file_and_line (const char *msg, ...)
10692477
RS
245{
246 char context[64];
247 size_t i;
248 int c;
249 va_list ap;
250
251 va_start (ap, msg);
252
3814e880
DM
253 fprintf (stderr, "%s:%d:%d: error: ", rtx_reader_ptr->get_filename (),
254 rtx_reader_ptr->get_lineno (), rtx_reader_ptr->get_colno ());
10692477
RS
255 vfprintf (stderr, msg, ap);
256 putc ('\n', stderr);
257
258 /* Gather some following context. */
259 for (i = 0; i < sizeof (context)-1; ++i)
260 {
c5e88b39 261 c = read_char ();
10692477
RS
262 if (c == EOF)
263 break;
264 if (c == '\r' || c == '\n')
7f7c467f
RS
265 {
266 unread_char (c);
267 break;
268 }
10692477
RS
269 context[i] = c;
270 }
271 context[i] = '\0';
272
3814e880 273 fprintf (stderr, "%s:%d:%d: note: following context is `%s'\n",
812b1403 274 rtx_reader_ptr->get_filename (), rtx_reader_ptr->get_lineno (),
3814e880 275 rtx_reader_ptr->get_colno (), context);
10692477
RS
276
277 va_end (ap);
278 exit (1);
279}
280
281/* Report that we found character ACTUAL when we expected to find
c5e88b39 282 character EXPECTED. */
10692477
RS
283
284void
c5e88b39 285fatal_expected_char (int expected, int actual)
10692477
RS
286{
287 if (actual == EOF)
c5e88b39 288 fatal_with_file_and_line ("expected character `%c', found EOF",
10692477
RS
289 expected);
290 else
c5e88b39 291 fatal_with_file_and_line ("expected character `%c', found `%c'",
10692477
RS
292 expected, actual);
293}
294
c5e88b39 295/* Read chars from the MD file until a non-whitespace char and return that.
10692477
RS
296 Comments, both Lisp style and C style, are treated as whitespace. */
297
298int
c5e88b39 299read_skip_spaces (void)
10692477
RS
300{
301 int c;
302
303 while (1)
304 {
c5e88b39 305 c = read_char ();
10692477
RS
306 switch (c)
307 {
7f7c467f 308 case ' ': case '\t': case '\f': case '\r': case '\n':
10692477
RS
309 break;
310
311 case ';':
312 do
c5e88b39 313 c = read_char ();
10692477 314 while (c != '\n' && c != EOF);
10692477
RS
315 break;
316
317 case '/':
318 {
319 int prevc;
c5e88b39 320 c = read_char ();
10692477 321 if (c != '*')
7f7c467f
RS
322 {
323 unread_char (c);
324 fatal_with_file_and_line ("stray '/' in file");
325 }
10692477
RS
326
327 prevc = 0;
c5e88b39 328 while ((c = read_char ()) && c != EOF)
10692477 329 {
7f7c467f 330 if (prevc == '*' && c == '/')
10692477
RS
331 break;
332 prevc = c;
333 }
334 }
335 break;
336
337 default:
338 return c;
339 }
340 }
341}
342
601070fc
DM
343/* Consume any whitespace, then consume the next non-whitespace
344 character, issuing a fatal error if it is not EXPECTED. */
345
346void
347require_char_ws (char expected)
348{
349 int ch = read_skip_spaces ();
350 if (ch != expected)
351 fatal_expected_char (expected, ch);
352}
353
812b1403
DM
354/* Read the next character from the file. */
355
356int
357rtx_reader::read_char (void)
358{
359 int ch;
360
361 ch = getc (m_read_md_file);
362 if (ch == '\n')
3814e880
DM
363 {
364 m_read_md_lineno++;
365 m_last_line_colno = m_read_md_colno;
366 m_read_md_colno = 0;
367 }
368 else
369 m_read_md_colno++;
812b1403
DM
370
371 return ch;
372}
373
374/* Put back CH, which was the last character read from the file. */
375
376void
377rtx_reader::unread_char (int ch)
378{
379 if (ch == '\n')
3814e880
DM
380 {
381 m_read_md_lineno--;
382 m_read_md_colno = m_last_line_colno;
383 }
384 else
385 m_read_md_colno--;
812b1403
DM
386 ungetc (ch, m_read_md_file);
387}
388
9f418533
RS
389/* Read an rtx code name into NAME. It is terminated by any of the
390 punctuation chars of rtx printed syntax. */
391
392void
b78027d1 393rtx_reader::read_name (struct md_name *name)
9f418533
RS
394{
395 int c;
396 size_t i;
4fe017f6 397 int angle_bracket_depth;
9f418533
RS
398
399 c = read_skip_spaces ();
400
401 i = 0;
4fe017f6 402 angle_bracket_depth = 0;
9f418533
RS
403 while (1)
404 {
4fe017f6
MC
405 if (c == '<')
406 angle_bracket_depth++;
407
408 if ((c == '>') && (angle_bracket_depth > 0))
409 angle_bracket_depth--;
410
9f418533
RS
411 if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r'
412 || c == EOF)
413 break;
4fe017f6 414 if (angle_bracket_depth == 0)
9f418533 415 {
4fe017f6
MC
416 if (c == ':' || c == ')' || c == ']'
417 || c == '"' || c == '/' || c == '(' || c == '[')
418 {
419 unread_char (c);
420 break;
421 }
9f418533
RS
422 }
423
424 if (i == sizeof (name->buffer) - 1)
425 fatal_with_file_and_line ("name too long");
426 name->buffer[i++] = c;
427
428 c = read_char ();
429 }
430
431 if (i == 0)
432 fatal_with_file_and_line ("missing name or number");
9f418533
RS
433
434 name->buffer[i] = 0;
435 name->string = name->buffer;
436
b78027d1 437 if (m_md_constants)
9f418533
RS
438 {
439 /* Do constant expansion. */
440 struct md_constant *def;
441
442 do
443 {
444 struct md_constant tmp_def;
445
446 tmp_def.name = name->string;
b78027d1 447 def = (struct md_constant *) htab_find (m_md_constants, &tmp_def);
9f418533
RS
448 if (def)
449 name->string = def->value;
450 }
451 while (def);
452 }
453}
454
10692477
RS
455/* Subroutine of the string readers. Handles backslash escapes.
456 Caller has read the backslash, but not placed it into the obstack. */
457
b78027d1
DM
458void
459rtx_reader::read_escape ()
10692477 460{
c5e88b39 461 int c = read_char ();
10692477
RS
462
463 switch (c)
464 {
465 /* Backslash-newline is replaced by nothing, as in C. */
466 case '\n':
10692477
RS
467 return;
468
469 /* \" \' \\ are replaced by the second character. */
470 case '\\':
471 case '"':
472 case '\'':
473 break;
474
475 /* Standard C string escapes:
476 \a \b \f \n \r \t \v
477 \[0-7] \x
478 all are passed through to the output string unmolested.
479 In normal use these wind up in a string constant processed
480 by the C compiler, which will translate them appropriately.
481 We do not bother checking that \[0-7] are followed by up to
482 two octal digits, or that \x is followed by N hex digits.
483 \? \u \U are left out because they are not in traditional C. */
484 case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
485 case '0': case '1': case '2': case '3': case '4': case '5': case '6':
486 case '7': case 'x':
b78027d1 487 obstack_1grow (&m_string_obstack, '\\');
10692477
RS
488 break;
489
490 /* \; makes stuff for a C string constant containing
491 newline and tab. */
492 case ';':
b78027d1 493 obstack_grow (&m_string_obstack, "\\n\\t", 4);
10692477
RS
494 return;
495
496 /* pass anything else through, but issue a warning. */
497 default:
498 fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
b78027d1 499 get_filename (), get_lineno (),
812b1403 500 c);
b78027d1 501 obstack_1grow (&m_string_obstack, '\\');
10692477
RS
502 break;
503 }
504
b78027d1 505 obstack_1grow (&m_string_obstack, c);
10692477
RS
506}
507
508/* Read a double-quoted string onto the obstack. Caller has scanned
509 the leading quote. */
510
511char *
b78027d1 512rtx_reader::read_quoted_string ()
10692477
RS
513{
514 int c;
515
516 while (1)
517 {
c5e88b39 518 c = read_char (); /* Read the string */
7f7c467f 519 if (c == '\\')
10692477 520 {
c5e88b39 521 read_escape ();
10692477
RS
522 continue;
523 }
524 else if (c == '"' || c == EOF)
525 break;
526
b78027d1 527 obstack_1grow (&m_string_obstack, c);
10692477
RS
528 }
529
b78027d1
DM
530 obstack_1grow (&m_string_obstack, 0);
531 return XOBFINISH (&m_string_obstack, char *);
10692477
RS
532}
533
534/* Read a braced string (a la Tcl) onto the string obstack. Caller
535 has scanned the leading brace. Note that unlike quoted strings,
536 the outermost braces _are_ included in the string constant. */
537
b78027d1
DM
538char *
539rtx_reader::read_braced_string ()
10692477
RS
540{
541 int c;
542 int brace_depth = 1; /* caller-processed */
b78027d1 543 unsigned long starting_read_md_lineno = get_lineno ();
10692477 544
b78027d1 545 obstack_1grow (&m_string_obstack, '{');
10692477
RS
546 while (brace_depth)
547 {
c5e88b39 548 c = read_char (); /* Read the string */
10692477 549
7f7c467f 550 if (c == '{')
10692477
RS
551 brace_depth++;
552 else if (c == '}')
553 brace_depth--;
554 else if (c == '\\')
555 {
c5e88b39 556 read_escape ();
10692477
RS
557 continue;
558 }
559 else if (c == EOF)
560 fatal_with_file_and_line
c5e88b39 561 ("missing closing } for opening brace on line %lu",
d2a3ce4e 562 starting_read_md_lineno);
10692477 563
b78027d1 564 obstack_1grow (&m_string_obstack, c);
10692477
RS
565 }
566
b78027d1
DM
567 obstack_1grow (&m_string_obstack, 0);
568 return XOBFINISH (&m_string_obstack, char *);
10692477
RS
569}
570
571/* Read some kind of string constant. This is the high-level routine
572 used by read_rtx. It handles surrounding parentheses, leading star,
573 and dispatch to the appropriate string constant reader. */
574
575char *
b78027d1 576rtx_reader::read_string (int star_if_braced)
10692477
RS
577{
578 char *stringbuf;
579 int saw_paren = 0;
580 int c, old_lineno;
581
c5e88b39 582 c = read_skip_spaces ();
10692477
RS
583 if (c == '(')
584 {
585 saw_paren = 1;
c5e88b39 586 c = read_skip_spaces ();
10692477
RS
587 }
588
b78027d1 589 old_lineno = get_lineno ();
10692477 590 if (c == '"')
c5e88b39 591 stringbuf = read_quoted_string ();
10692477
RS
592 else if (c == '{')
593 {
594 if (star_if_braced)
b78027d1 595 obstack_1grow (&m_string_obstack, '*');
c5e88b39 596 stringbuf = read_braced_string ();
10692477
RS
597 }
598 else
c5e88b39 599 fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);
10692477
RS
600
601 if (saw_paren)
601070fc 602 require_char_ws (')');
10692477 603
b78027d1 604 set_md_ptr_loc (stringbuf, get_filename (), old_lineno);
10692477
RS
605 return stringbuf;
606}
607
9b68b6ea
RS
608/* Skip the rest of a construct that started at line LINENO and that
609 is currently nested by DEPTH levels of parentheses. */
610
b78027d1
DM
611void
612rtx_reader::read_skip_construct (int depth, file_location loc)
9b68b6ea
RS
613{
614 struct md_name name;
615 int c;
616
617 do
618 {
619 c = read_skip_spaces ();
620 if (c == EOF)
621 {
cc472607 622 error_at (loc, "unterminated construct");
9b68b6ea
RS
623 exit (1);
624 }
625 switch (c)
626 {
627 case '(':
628 depth++;
629 break;
630
631 case ')':
632 depth--;
633 break;
634
635 case ':':
636 case '[':
637 case ']':
638 case '/':
639 break;
640
641 case '\"':
642 case '{':
643 unread_char (c);
644 read_string (false);
645 break;
646
647 default:
648 unread_char (c);
649 read_name (&name);
650 break;
651 }
652 }
653 while (depth > 0);
654 unread_char (c);
655}
656
10692477
RS
657/* Given a string, return the number of comma-separated elements in it.
658 Return 0 for the null string. */
659
660int
661n_comma_elts (const char *s)
662{
663 int n;
664
665 if (*s == '\0')
666 return 0;
667
668 for (n = 1; *s; s++)
669 if (*s == ',')
670 n++;
671
672 return n;
673}
674
675/* Given a pointer to a (char *), return a pointer to the beginning of the
676 next comma-separated element in the string. Advance the pointer given
677 to the end of that element. Return NULL if at end of string. Caller
678 is responsible for copying the string if necessary. White space between
679 a comma and an element is ignored. */
680
681const char *
682scan_comma_elt (const char **pstr)
683{
684 const char *start;
685 const char *p = *pstr;
686
687 if (*p == ',')
688 p++;
c3284718 689 while (ISSPACE (*p))
10692477
RS
690 p++;
691
692 if (*p == '\0')
693 return NULL;
694
695 start = p;
696
697 while (*p != ',' && *p != '\0')
698 p++;
699
700 *pstr = p;
701 return start;
702}
703
24609606
RS
704/* Convert STRING to uppercase. */
705
706void
707upcase_string (char *string)
708{
709 int i;
710
711 for (i = 0; string[i]; i++)
712 string[i] = TOUPPER (string[i]);
713}
714
715/* Add a NAME = VALUE definition to md_constants-style hash table DEFS,
716 where both NAME and VALUE are malloc()ed strings. PARENT_ENUM is the
717 enum to which NAME belongs, or null if NAME is a stand-alone constant. */
718
719static struct md_constant *
720add_constant (htab_t defs, char *name, char *value,
721 struct enum_type *parent_enum)
722{
723 struct md_constant *def, tmp_def;
724 void **entry_ptr;
725
726 tmp_def.name = name;
727 entry_ptr = htab_find_slot (defs, &tmp_def, INSERT);
728 if (*entry_ptr)
729 {
730 def = (struct md_constant *) *entry_ptr;
731 if (strcmp (def->value, value) != 0)
732 fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'",
733 def->name, def->value, value);
734 else if (parent_enum || def->parent_enum)
735 fatal_with_file_and_line ("redefinition of `%s'", def->name);
736 free (name);
737 free (value);
738 }
739 else
740 {
741 def = XNEW (struct md_constant);
742 def->name = name;
743 def->value = value;
744 def->parent_enum = parent_enum;
745 *entry_ptr = def;
746 }
747 return def;
748}
749
9f418533
RS
750/* Process a define_constants directive, starting with the optional space
751 after the "define_constants". */
752
b78027d1
DM
753void
754rtx_reader::handle_constants ()
9f418533
RS
755{
756 int c;
757 htab_t defs;
758
601070fc 759 require_char_ws ('[');
9f418533
RS
760
761 /* Disable constant expansion during definition processing. */
b78027d1
DM
762 defs = m_md_constants;
763 m_md_constants = 0;
9f418533
RS
764 while ( (c = read_skip_spaces ()) != ']')
765 {
766 struct md_name name, value;
9f418533
RS
767
768 if (c != '(')
769 fatal_expected_char ('(', c);
770
771 read_name (&name);
772 read_name (&value);
24609606 773 add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);
9f418533 774
601070fc 775 require_char_ws (')');
9f418533 776 }
b78027d1 777 m_md_constants = defs;
9f418533
RS
778}
779
780/* For every constant definition, call CALLBACK with two arguments:
781 a pointer a pointer to the constant definition and INFO.
782 Stop when CALLBACK returns zero. */
783
784void
b78027d1 785rtx_reader::traverse_md_constants (htab_trav callback, void *info)
9f418533 786{
b78027d1 787 htab_traverse (get_md_constants (), callback, info);
24609606
RS
788}
789
790/* Return a malloc()ed decimal string that represents number NUMBER. */
791
792static char *
09e9c1e0 793md_decimal_string (int number)
24609606
RS
794{
795 /* A safe overestimate. +1 for sign, +1 for null terminator. */
796 char buffer[sizeof (int) * CHAR_BIT + 1 + 1];
797
798 sprintf (buffer, "%d", number);
799 return xstrdup (buffer);
800}
801
802/* Process a define_enum or define_c_enum directive, starting with
803 the optional space after the "define_enum". LINENO is the line
804 number on which the directive started and MD_P is true if the
805 directive is a define_enum rather than a define_c_enum. */
806
b78027d1
DM
807void
808rtx_reader::handle_enum (file_location loc, bool md_p)
24609606
RS
809{
810 char *enum_name, *value_name;
811 struct md_name name;
812 struct enum_type *def;
813 struct enum_value *ev;
814 void **slot;
815 int c;
816
817 enum_name = read_string (false);
b78027d1 818 slot = htab_find_slot (m_enum_types, &enum_name, INSERT);
24609606
RS
819 if (*slot)
820 {
821 def = (struct enum_type *) *slot;
822 if (def->md_p != md_p)
cc472607
RS
823 error_at (loc, "redefining `%s' as a different type of enum",
824 enum_name);
24609606
RS
825 }
826 else
827 {
828 def = XNEW (struct enum_type);
829 def->name = enum_name;
830 def->md_p = md_p;
831 def->values = 0;
832 def->tail_ptr = &def->values;
833 def->num_values = 0;
834 *slot = def;
835 }
836
601070fc 837 require_char_ws ('[');
24609606
RS
838
839 while ((c = read_skip_spaces ()) != ']')
840 {
841 if (c == EOF)
842 {
cc472607 843 error_at (loc, "unterminated construct");
24609606
RS
844 exit (1);
845 }
846 unread_char (c);
847 read_name (&name);
848
849 ev = XNEW (struct enum_value);
850 ev->next = 0;
851 if (md_p)
852 {
853 value_name = concat (def->name, "_", name.string, NULL);
854 upcase_string (value_name);
855 ev->name = xstrdup (name.string);
856 }
857 else
858 {
859 value_name = xstrdup (name.string);
860 ev->name = value_name;
861 }
b78027d1 862 ev->def = add_constant (get_md_constants (), value_name,
09e9c1e0 863 md_decimal_string (def->num_values), def);
24609606
RS
864
865 *def->tail_ptr = ev;
866 def->tail_ptr = &ev->next;
867 def->num_values++;
868 }
869}
870
8f4fe86c
RS
871/* Try to find the definition of the given enum. Return null on failure. */
872
873struct enum_type *
b78027d1 874rtx_reader::lookup_enum_type (const char *name)
8f4fe86c 875{
b78027d1 876 return (struct enum_type *) htab_find (m_enum_types, &name);
8f4fe86c
RS
877}
878
24609606
RS
879/* For every enum definition, call CALLBACK with two arguments:
880 a pointer to the constant definition and INFO. Stop when CALLBACK
881 returns zero. */
882
883void
b78027d1 884rtx_reader::traverse_enum_types (htab_trav callback, void *info)
24609606 885{
b78027d1 886 htab_traverse (m_enum_types, callback, info);
9f418533
RS
887}
888
812b1403
DM
889
890/* Constructor for rtx_reader. */
891
892rtx_reader::rtx_reader ()
893: m_toplevel_fname (NULL),
894 m_base_dir (NULL),
895 m_read_md_file (NULL),
896 m_read_md_filename (NULL),
897 m_read_md_lineno (0),
3814e880 898 m_read_md_colno (0),
812b1403
DM
899 m_first_dir_md_include (NULL),
900 m_last_dir_md_include_ptr (&m_first_dir_md_include)
901{
902 /* Set the global singleton pointer. */
903 rtx_reader_ptr = this;
b78027d1
DM
904
905 obstack_init (&m_string_obstack);
906
907 m_ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
908 obstack_init (&m_ptr_loc_obstack);
909
910 m_joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
911 obstack_init (&m_joined_conditions_obstack);
912
913 m_md_constants = htab_create (31, leading_string_hash,
914 leading_string_eq_p, (htab_del) 0);
915
916 m_enum_types = htab_create (31, leading_string_hash,
917 leading_string_eq_p, (htab_del) 0);
918
919 /* Unlock the stdio streams. */
920 unlock_std_streams ();
812b1403
DM
921}
922
923/* rtx_reader's destructor. */
924
925rtx_reader::~rtx_reader ()
926{
b78027d1
DM
927 free (m_base_dir);
928
929 htab_delete (m_enum_types);
930
931 htab_delete (m_md_constants);
932
933 obstack_free (&m_joined_conditions_obstack, NULL);
934 htab_delete (m_joined_conditions);
935
936 obstack_free (&m_ptr_loc_obstack, NULL);
937 htab_delete (m_ptr_locs);
938
939 obstack_free (&m_string_obstack, NULL);
940
812b1403
DM
941 /* Clear the global singleton pointer. */
942 rtx_reader_ptr = NULL;
943}
944
600ab3fc
RS
945/* Process an "include" directive, starting with the optional space
946 after the "include". Read in the file and use HANDLE_DIRECTIVE
947 to process each unknown directive. LINENO is the line number on
1aa95df7 948 which the "include" occurred. */
10692477 949
812b1403
DM
950void
951rtx_reader::handle_include (file_location loc)
10692477 952{
600ab3fc
RS
953 const char *filename;
954 const char *old_filename;
3814e880 955 int old_lineno, old_colno;
600ab3fc
RS
956 char *pathname;
957 FILE *input_file, *old_file;
958
959 filename = read_string (false);
960 input_file = NULL;
961
962 /* If the specified file name is absolute, skip the include stack. */
963 if (!IS_ABSOLUTE_PATH (filename))
964 {
965 struct file_name_list *stackp;
966
967 /* Search the directory path, trying to open the file. */
812b1403 968 for (stackp = m_first_dir_md_include; stackp; stackp = stackp->next)
600ab3fc
RS
969 {
970 static const char sep[2] = { DIR_SEPARATOR, '\0' };
971
972 pathname = concat (stackp->fname, sep, filename, NULL);
973 input_file = fopen (pathname, "r");
974 if (input_file != NULL)
975 break;
976 free (pathname);
977 }
978 }
979
980 /* If we haven't managed to open the file yet, try combining the
981 filename with BASE_DIR. */
982 if (input_file == NULL)
983 {
812b1403
DM
984 if (m_base_dir)
985 pathname = concat (m_base_dir, filename, NULL);
600ab3fc
RS
986 else
987 pathname = xstrdup (filename);
988 input_file = fopen (pathname, "r");
989 }
990
991 if (input_file == NULL)
992 {
993 free (pathname);
cc472607 994 error_at (loc, "include file `%s' not found", filename);
600ab3fc
RS
995 return;
996 }
997
998 /* Save the old cursor. Note that the LINENO argument to this
999 function is the beginning of the include statement, while
1000 read_md_lineno has already been advanced. */
812b1403
DM
1001 old_file = m_read_md_file;
1002 old_filename = m_read_md_filename;
1003 old_lineno = m_read_md_lineno;
3814e880 1004 old_colno = m_read_md_colno;
600ab3fc
RS
1005
1006 if (include_callback)
1007 include_callback (pathname);
1008
812b1403
DM
1009 m_read_md_file = input_file;
1010 m_read_md_filename = pathname;
1011
1012 handle_file ();
600ab3fc
RS
1013
1014 /* Restore the old cursor. */
812b1403
DM
1015 m_read_md_file = old_file;
1016 m_read_md_filename = old_filename;
1017 m_read_md_lineno = old_lineno;
3814e880 1018 m_read_md_colno = old_colno;
600ab3fc
RS
1019
1020 /* Do not free the pathname. It is attached to the various rtx
1021 queue elements. */
1022}
1023
1024/* Process the current file, assuming that read_md_file and
1025 read_md_filename are valid. Use HANDLE_DIRECTIVE to handle
1026 unknown directives. */
1027
812b1403
DM
1028void
1029rtx_reader::handle_file ()
600ab3fc
RS
1030{
1031 struct md_name directive;
cc472607 1032 int c;
600ab3fc 1033
812b1403 1034 m_read_md_lineno = 1;
3814e880 1035 m_read_md_colno = 0;
600ab3fc
RS
1036 while ((c = read_skip_spaces ()) != EOF)
1037 {
812b1403 1038 file_location loc = get_current_location ();
600ab3fc
RS
1039 if (c != '(')
1040 fatal_expected_char ('(', c);
1041
1042 read_name (&directive);
1043 if (strcmp (directive.string, "define_constants") == 0)
1044 handle_constants ();
24609606 1045 else if (strcmp (directive.string, "define_enum") == 0)
cc472607 1046 handle_enum (loc, true);
24609606 1047 else if (strcmp (directive.string, "define_c_enum") == 0)
cc472607 1048 handle_enum (loc, false);
600ab3fc 1049 else if (strcmp (directive.string, "include") == 0)
812b1403 1050 handle_include (loc);
9b68b6ea 1051 else
812b1403 1052 handle_unknown_directive (loc, directive.string);
600ab3fc 1053
601070fc 1054 require_char_ws (')');
600ab3fc 1055 }
812b1403 1056 fclose (m_read_md_file);
600ab3fc
RS
1057}
1058
812b1403
DM
1059/* Like handle_file, but for top-level files. Set up m_toplevel_fname
1060 and m_base_dir accordingly. */
600ab3fc 1061
812b1403
DM
1062void
1063rtx_reader::handle_toplevel_file ()
600ab3fc 1064{
ba78087b 1065 const char *base;
600ab3fc 1066
812b1403
DM
1067 m_toplevel_fname = m_read_md_filename;
1068 base = lbasename (m_toplevel_fname);
1069 if (base == m_toplevel_fname)
1070 m_base_dir = NULL;
ba78087b 1071 else
812b1403
DM
1072 m_base_dir = xstrndup (m_toplevel_fname, base - m_toplevel_fname);
1073
1074 handle_file ();
1075}
600ab3fc 1076
812b1403
DM
1077file_location
1078rtx_reader::get_current_location () const
1079{
3814e880 1080 return file_location (m_read_md_filename, m_read_md_lineno, m_read_md_colno);
600ab3fc
RS
1081}
1082
1083/* Parse a -I option with argument ARG. */
1084
812b1403
DM
1085void
1086rtx_reader::add_include_path (const char *arg)
600ab3fc
RS
1087{
1088 struct file_name_list *dirtmp;
1089
1090 dirtmp = XNEW (struct file_name_list);
1091 dirtmp->next = 0;
1092 dirtmp->fname = arg;
812b1403
DM
1093 *m_last_dir_md_include_ptr = dirtmp;
1094 m_last_dir_md_include_ptr = &dirtmp->next;
600ab3fc
RS
1095}
1096
1097/* The main routine for reading .md files. Try to process all the .md
1aa95df7 1098 files specified on the command line and return true if no error occurred.
600ab3fc
RS
1099
1100 ARGC and ARGV are the arguments to main.
1101
1102 PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
1103 It should return true if it recognizes the argument or false if a
812b1403 1104 generic error should be reported. */
600ab3fc
RS
1105
1106bool
812b1403
DM
1107rtx_reader::read_md_files (int argc, const char **argv,
1108 bool (*parse_opt) (const char *))
600ab3fc
RS
1109{
1110 int i;
1111 bool no_more_options;
1112 bool already_read_stdin;
1113 int num_files;
1114
600ab3fc
RS
1115 /* First we loop over all the options. */
1116 for (i = 1; i < argc; i++)
1117 if (argv[i][0] == '-')
1118 {
1119 /* An argument consisting of exactly one dash is a request to
1120 read stdin. This will be handled in the second loop. */
1121 if (argv[i][1] == '\0')
1122 continue;
1123
1124 /* An argument consisting of just two dashes causes option
1125 parsing to cease. */
1126 if (argv[i][1] == '-' && argv[i][2] == '\0')
1127 break;
1128
1129 if (argv[i][1] == 'I')
1130 {
1131 if (argv[i][2] != '\0')
812b1403 1132 add_include_path (argv[i] + 2);
600ab3fc 1133 else if (++i < argc)
812b1403 1134 add_include_path (argv[i]);
600ab3fc
RS
1135 else
1136 fatal ("directory name missing after -I option");
1137 continue;
1138 }
1139
1140 /* The program may have provided a callback so it can
1141 accept its own options. */
1142 if (parse_opt && parse_opt (argv[i]))
1143 continue;
1144
1145 fatal ("invalid option `%s'", argv[i]);
1146 }
1147
1148 /* Now loop over all input files. */
1149 num_files = 0;
1150 no_more_options = false;
1151 already_read_stdin = false;
1152 for (i = 1; i < argc; i++)
1153 {
1154 if (argv[i][0] == '-')
1155 {
1156 if (argv[i][1] == '\0')
1157 {
1158 /* Read stdin. */
1159 if (already_read_stdin)
1160 fatal ("cannot read standard input twice");
1161
812b1403
DM
1162 m_read_md_file = stdin;
1163 m_read_md_filename = "<stdin>";
1164 handle_toplevel_file ();
600ab3fc
RS
1165 already_read_stdin = true;
1166 continue;
1167 }
1168 else if (argv[i][1] == '-' && argv[i][2] == '\0')
1169 {
1170 /* No further arguments are to be treated as options. */
1171 no_more_options = true;
1172 continue;
1173 }
1174 else if (!no_more_options)
1175 continue;
1176 }
1177
1178 /* If we get here we are looking at a non-option argument, i.e.
1179 a file to be processed. */
812b1403
DM
1180 m_read_md_filename = argv[i];
1181 m_read_md_file = fopen (m_read_md_filename, "r");
1182 if (m_read_md_file == 0)
600ab3fc 1183 {
812b1403 1184 perror (m_read_md_filename);
600ab3fc
RS
1185 return false;
1186 }
812b1403 1187 handle_toplevel_file ();
600ab3fc
RS
1188 num_files++;
1189 }
1190
1191 /* If we get to this point without having seen any files to process,
1192 read the standard input now. */
1193 if (num_files == 0 && !already_read_stdin)
1194 {
812b1403
DM
1195 m_read_md_file = stdin;
1196 m_read_md_filename = "<stdin>";
1197 handle_toplevel_file ();
600ab3fc
RS
1198 }
1199
1200 return !have_error;
10692477 1201}
812b1403
DM
1202
1203/* class noop_reader : public rtx_reader */
1204
1205/* A dummy implementation which skips unknown directives. */
1206void
1207noop_reader::handle_unknown_directive (file_location loc, const char *)
1208{
1209 read_skip_construct (1, loc);
1210}